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

来源:互联网 发布:java读取blob字段 编辑:程序博客网 时间:2024/05/22 16:52

前一阵子,一个在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 QueensN=8P=8def 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 0def 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 Falsedef 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 Truesolve()for i in range(N):    F[ans[i]/N][ans[i]%N]=1print 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;}




原创粉丝点击