您的位置:首页 > 大数据 > 人工智能

八皇后问题变种 硅谷AI硕士作业题 One assignment of the MSc in USC

2017-10-20 17:07 316 查看
前一阵子,一个在USC读书(master in AI)的哥们发来了他们一门课的作业题,让我帮着看看,我就试着写了一下,学习了学习,想看看美帝硅谷的CS学生都在学什么。

题目是这样的:

读入一个文件,which描述了一个N*N的矩阵,里面有些障碍物,然后要往里放皇后(国象的后),要使得他们之间互不能影响到。然后现在要求我们用三种方法解决这个问题:DFS、BFS、SA,分别是深搜、宽搜、模拟退火。作业的pdf文件很长,我节选了一下原文:

You will write a program that will take an input file that has an arrangement of trees and will output a new arrangement of lizards (and trees; as already mentioned, you
can’t move the trees) such that no baby lizard can eat another one. You will be required to create a program that finds the solution. To find the solution you will use the following algorithms:
- Breadth-first search (BFS)
- Depth-first search (DFS)
- Simulated annealing (SA).
Input: The file
input.txt in the current directory of your program will be formatted as follows:
First line:
instruction of which algorithm to use: BFS, DFS or SA
Second line:
strictly positive 32-bit integer n, the width and height of the square nursery
Third line:
strictly positive 32-bit integer p, the number of baby lizards
Next n lines:
the n x n nursery, one file line per nursery row (to show you where the trees are).

It will have a 0 where there is nothing, and a 2 where there is a tree.So for instance, an input file arranged like figure 2B (but with no lizards yet) and requesting you to use the DFS algorithm to place 8 lizards in the 8x8 nursery would look like:

DFS

88

00000000

00000000

00000000

00002000

00000000

00000200

00000000

00000000
Output: The file
output.txt which your program creates in the current directory should be formatted as follows:
First line:
OK or FAIL, indicating whether a solution was found or not.

If FAIL, any following lines are ignored.
Next n lines:
the n x n nursery, one line in the file per nursery row, including the baby lizards

and trees. It will have a 0 where there is nothing, a 1 where you placed a baby lizard, and a 2 where there is a tree.

For example, a correct output.txt for the above sample input.txt (and matching Figure 2B) is:
OK
00000100

10000000

00001000

01002001

00000000

00100200

00000010

00010000

对于这个问题,我写了BFS和DFS的代码解决掉了,SA的我没写,哥们写的。

怎么说呢,BFS写了个结点(Node)保存了很多状态,比较麻烦把,DFS相对直观暴力一些。

DFS代码(py):

F=[
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
]
ans=[]#the position of Queens
N=8
P=8
def solve():#N is the Size of raw and col,P is the number of Queens
#read in F,N,P
startp=-1
for i in range(N*N):
if F[i/N][i%N]==0:
startp=i
break
if startp==-1:
print "FALL"
return 0
if dfs(P,startp):
print "OK"
print ans
else:
print "FALL"

return 0

def dfs(num,startP):#number of Queens left,start Position
if num==0:return True
for i in range(startP,N*N):
if F[i/N][i%N]==0 and judge(i):
ans.append(i)
if dfs(num-1,i+1):return True
ans.pop()
return False
def judge(position):#judge whether valid
ansLen=len(ans)
for i in range(ansLen):
curx=ans[i]/N
cury=ans[i]%N
px=position/N
py=position%N
dx=curx-px
dy=cury-py
if dx==0 or dy==0 or abs(dx)==abs(dy):
if dx!=0:dx=dx/abs(dx)
if dy!=0:dy=dy/abs(dy)
flag=0
while (not(px == curx and py == cury)):
px += dx
py += dy
if (F[px][py] == 2):
flag=1
break
if flag==0:
return False
return True

solve()
for i in range(N):
F[ans[i]/N][ans[i]%N]=1
print F


BFS代码(cpp):

#include <bits/stdc++.h>
#pragma comment(linker,"/STACK:1024000000,1024000000")
using namespace std;
const int MAX_SIZE=1000;
int N,P;
int F[MAX_SIZE][MAX_SIZE];
char inputS[5];

struct Point{
int x,y;
Point(){}
Point(int X,int Y){
x=X;
y=Y;
}
};
vector<Point>ans;

struct Node{
int cnt;
vector<Point>S;
Node(){}
Node(int c,vector<Point>inS){
cnt=c;
S=inS;
}
void addP(Point p){
cnt+=1;
S.push_back(p);
}
bool judgeP(Point p){
int fuck=0;
for(int i=0;i<cnt;i++){
int curx=S[i].x;
int cury=S[i].y;
int px=p.x;
int py=p.y;
int dx=curx-px;
int dy=cury-py;
if(dx==0||dy==0||abs(dx)==abs(dy)){
if(dx!=0)dx=dx/abs(dx);
if(dy!=0)dy=dy/abs(dy);
int flag=0;
while(!(px==curx&&py==cury)){
px+=dx;
py+=dy;
if(F[px][py]==2){
flag=1;
break;
}
}
if(flag==0){
return false;
}
}
}
return true;
}

};

bool bfs(Point inP){
queue<Node>q;
vector<Point>init;
init.push_back(inP);
Node firstNode=Node(1,init);
q.push(firstNode);
while(!q.empty()){
Node cur=q.front();
q.pop();
if(cur.cnt==P){
ans=cur.S;
return true;
}
Point lastP=cur.S[cur.cnt-1];
int curx=lastP.x;
int cury=lastP.y;
for(int i=curx*N+cury+1;i<N*N;i++){
int newx=i/N;
int newy=i%N;
if(F[newx][newy]!=2&&cur.judgeP(Point(newx,newy))){
Node newNode=cur;
newNode.addP(Point(newx,newy));
q.push(newNode);
}
}
}
return false;
}

int main(){
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
cin>>inputS;
if(inputS[0]=='B'){
cin>>N>>P;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
char c;
scanf(" %c",&c);
F[i][j]=c-'0';
}
}
bool flag=0;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(F[i][j]!=2){
flag=bfs(Point(i,j));
if(flag)break;
}
}
if(flag)break;
}
if (flag){
for(int i=0;i<ans.size();i++){
F[ans[i].x][ans[i].y]=1;
}
cout<<"OK"<<endl;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
printf("%d",F[i][j]);
}printf("\n");
}
}
else{
cout<<"FALL"<<endl;
}

}
fclose(stdin);
fclose(stdout);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐