人工智能作业 三个野人和三个传教士
2011-03-28 10:15
218 查看
/* 三个野人,三个牧师过河问题,要求任意时刻野人人数不能多于牧师的人数。 算法: 广搜穷举。A*不知道怎样写。。。 程序实现了选择走最少次数的一个解,并不是所有的可行解。 */ #include<iostream> #include<deque> #include<algorithm> using namespace std; struct point{ int a,b,s,f;//a,表示出发岸牧师的人数,b表示野人的人数,对岸的人数可以通过简单的运算得到。 s表示当前是在岸的那边,0表示在出发岸,1表示在对岸;f表示父节点的位置 point(int a,int b,int s,int f):a(a),b(b),s(s),f(f){} }; deque<point> dq;//广搜队列; bool operator==(const point& p1,const point& p2){return p1.a==p2.a&&p1.b==p2.b&&p1.s==p2.s;} ostream& operator<<(ostream& _os,const point& p){//输出状态 return _os<<"["<<p.a<<","<<p.b<<","<<p.s<<","<<p.f<<"]"; } bool ishave(int a,int b,int s){//判断当前状态是否出现过 if(find(dq.begin(),dq.end(),point(a,b,s,0))!=dq.end())return 1; return 0; } bool isgo(int a,int b,int s)//用来判断时候可以过去 { if(s==0){ if(a<0||b<0||a>3||b>3)return 0; if(a!=0&&a<b)return 0; return 1; }else{ int a1=3-a,b1=3-b; if(a1<0||b1<0||a1>3||b1>3)return 0; if(a1!=0&&a1<b1)return 0; return 1; } } //显示一条移动最少次数的路径 void show(int pos) { if(dq[pos].f==pos){ cout<<dq[pos]<<endl; return; } show(dq[pos].f); cout<<dq[pos]<<endl; } int main() { int a=3,b=3,s; int pos=0;//当前节点的位置 dq.push_back(point(a,b,0,0)); while(pos!=dq.size()){//当还有元素可以加入的时候加入循环 a=dq[pos].a; b=dq[pos].b; s=dq[pos].s; if(a==0&&b==0&&s==1)break; if(dq[pos].s==0){//出发,5种情况列举 if(a<b&&a!=0){pos++;continue;}//状态不可用 if(isgo(a,b-2,0)&&!ishave(a,b-2,1)) dq.push_back(point(a,b-2,1,pos)); if(isgo(a-2,b,0)&&!ishave(a-2,b,1)) dq.push_back(point(a-2,b,1,pos)); if(isgo(a-1,b-1,0)&&!ishave(a-1,b-1,1)) dq.push_back(point(a-1,b-1,1,pos)); if(isgo(a-1,b,0)&&!ishave(a-1,b,1)) dq.push_back(point(a-1,b,1,pos)); if(isgo(a,b-1,0)&&!ishave(a,b-1,1)) dq.push_back(point(a,b-1,1,pos)); }else{//回来 if((3-a)!=0&&(3-a)<(3-b)){pos++;continue;}//状态不可用 if(isgo(a+2,b,1)&&!ishave(a+2,b,0)) dq.push_back(point(a+2,b,0,pos)); if(isgo(a,b+2,1)&&!ishave(a,b+2,0)) dq.push_back(point(a,b+2,0,pos)); if(isgo(a+1,b+1,1)&&!ishave(a+1,b+1,0)) dq.push_back(point(a+1,b+1,0,pos)); if(isgo(a+1,b,1)&&!ishave(a+1,b,0)) dq.push_back(point(a+1,b,0,pos)); if(isgo(a,b+1,1)&&!ishave(a,b+1,0)) dq.push_back(point(a,b+1,0,pos)); } pos++; } /*队列状态*/ for(int i=0;i<dq.size();i++) cout<<i<<": "<<dq[i]<<endl; //显示一条最优路径 cout<<"----------------------"<<endl; show(pos); }
相关文章推荐
- 【人工智能】传教士和野人问题(M-C问题)
- 三个传教士和三个野人过河
- 数据结构课设:三个野人和三个传教士(C实现)
- 作业: 编写一个JFrame窗口,要求如下: 1. 在窗口的NORTH区放置一个JPanel面板。 2. JPanel面板放置如下组件: (1) JLable标签,标签文本为“兴趣”,右边接着是三个J
- 野人传教士过河
- 传教士与野人问题
- .net(三个简单的作业)
- 传教士 野人 过河问题
- 传教士野人过河问题
- .net(三个简单的作业)
- 麦肯锡:人工智能三个关键业务方向 | PerceptIn获金蝶国际A+轮融资
- A*算法————传教士和野人
- 野人传教士问题——盲目搜索
- 用人工智能改变医疗,必须经过这三个阶段
- 野人传教士过河问题
- 研一的人工智能课程作业
- 人工智能作业--如何转动使得每个扇区数字和为12
- 传教士野人过河问题---Java版本
- 【转】传教士和野人问题(Missionaries and Cannibals)
- 初探计算机视觉的三个源头、兼谈人工智能|正本清源