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

人工智能作业 三个野人和三个传教士

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);
}
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  作业 算法 os