野人过河
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程实验报告
1.实验目的
掌握人工智能程序设计语言Prolog描述一般性的实际问题的程序编写方法。理解通过搜索求解问题实现人工智能的思想。
2.实验要求
要求学生对野人过河以及基本搜索算法有一定的了解
3.实验内容
设有3个传教士和3个野人同在河的左岸,他们都要到对岸去;河里只有一条船,他们都会划船,但每次渡船至多只能乘两人;如果在任何一边河岸上,野人的数量超过传教士,野人就要吃掉传教士,问怎样才能用船将3个传教士和3个野人从左岸都渡到右岸,又不会发生传教士被吃的事件呢?通过Prolog程序,给出乘船过河的动作序列。
理解问题所在,并将该问题抽象为对状态空间的搜索问题。设计搜索算法,解决该问题。该问题可以使用自己擅长的计算机语言来解决。
4.实验软硬件环境
基本Windows系统基本运行环境,Visual Prolog;dev c++;
5.实验方案
(1)设置该问题的状态。例如:((左岸牧师数,左岸野人数),(右岸牧师数,右岸野人数),船的位置)。
(2)定义目标状态。这里是:((0,0),(3,3),1):((左岸牧师数,左岸野人数),(右岸牧师数,右岸野人数),船的位置)
(3)描述可能的动作。船上所能够载人的状态就是可能的操作。用谓词move 表示。如:move(1,0).表示船上有一位牧师,没有野人。
(4)判断合法状态。如:legal((X,Y,_)):- %X为左岸状态,Y为右岸状态。(5)深度优先搜索。Findroad。
6.实验过程
三个传教士和三个野人的示例程序如下:
move(1,0).
move(0,1).
move(0,2).
move(2,0).
move(1,1).
legal((X,Y,_)):-legal1(X),legal1(Y).
legal1((X,Y)):-X=:=0,Y>=0,!.
legal1((X,Y)):-Y=:=0,X>=0,!.
legal1((X,Y)):-X>=Y,X>=0,Y>=0.
update((X,Y,0),Move,Statu1):-
(A,B)=X,
(C,D)=Y,
(E,F)=Move,
C1 is C+E,
D1 is D+F,
A1 is A-E,
B1 is B-F,
Statu1=((A1,B1),(C1,D1),1). update((X,Y,1),Move,Statu1):- (A,B)=X,
(C,D)=Y,
(E,F)=Move,
C1 is C-E,
D1 is D-F,
A1 is A+E,
B1 is B+F,
Statu1=((A1,B1),(C1,D1),0). connect(Statu,Statu1):-
move(X,Y),
update(Statu,(X,Y),Statu1), legal(Statu1).
findroad(X,X,L,L):-write(L). findroad(X,Y,L,L1):-
connect(X,Z),
not(member(Z,L)),
findroad(Z,Y,[Z|L],L1).
但是在visual prolog上运行不起来。。。
所以用c++,深度优先算法搜索
#include
#include
#include
#include
using namespace std;
bool flag = true; //true:表示在右岸
vector
bool dfs( int M, int C, int m, int c){
if( M<0||C<0||m<0||c<0) //非法
return false;
if( (M&&C>M) ||(m&&c>m)) //野人会吃牧师
return false;
if( flag&&M==0&&C==0 ||(!flag&&m==0&&c==0)) //全部运输过去return true;
//检查该节点是否出现过
char s[30];
if( !flag )
sprintf( s, "M=%d,C=%d,m=%d,c=%d,boat=left", M,C,m,c); else
sprintf( s, "M=%d,C=%d,m=%d,c=%d,boat=right", m,c,M,C); string str(s);
for( int i=0; i if( visit[i]==str) //该状态已经搜索过了return false; visit.push_back(str); flag = !flag; if( dfs( m+2, c, M-2,C) ){ printf("2,0\n"); printf("%s\n",s); return true; } else if( dfs( m, c+2, M, C-2) ){ printf("0,2\n"); printf("%s\n",s); return true; } else if( dfs( m+1, c+1, M-1, C-1) ){ printf("1,1\n"); printf("%s\n",s); return true; } else if( dfs( m+1, c, M-1, C)){ printf("1,0\n"); printf("%s\n",s); return true; } else if( dfs( m, c+1, M, C-1)){ printf("0,1\n"); printf("%s\n",s); return true; } flag = !flag; visit.pop_back(); return false;