人工智能:野人与修道士问题

合集下载

修道士与野人问题

修道士与野人问题

.修道士与野人问题这是一个古典问题。

假设有n个修道士和n个野人准备渡河,但只有一条能容纳c人的小船,为了防止野人侵犯修道士,要求无论在何处,修道士的个数不得少于野人的人数(除非修道士个数为0)。

如果两种人都会划船,试设计一个算法,确定他们能否渡过河去,若能,则给出一个小船来回次数最少的最佳方案。

要求:(1)用一个三元组(x1,x2,x3)表示渡河过程中各个状态。

其中,x1表示起始岸上修道士个数,x2表示起始岸上野人个数,x3表示小船位置(0——在目的岸,1——在起始岸)。

例如(2,1,1)表示起始岸上有两个修道士,一个野人,小船在起始岸一边。

采用邻接表做为存储结构,将各种状态之间的迁移图保存下来。

(2)采用广度搜索法,得到首先搜索到的边数最少的一条通路。

(3)输出数据若问题有解(能渡过河去),则输出一个最佳方案。

用三元组表示渡河过程中的状态,并用箭头指出这些状态之间的迁移:目的状态←…中间状态←…初始状态。

若问题无解,则给出“渡河失败”的信息。

(4)求出所有的解。

1.需求分析有n个修道士和n个野人准备渡河,但只有一条能容纳c人的小船,为了防止野人侵犯修道士,要求无论在何处,修道士的个数不得少于野人的人数,否则修道士就会有危险,设计一个算法,确定他们能否渡过河去,若能,则给出一个小船来回次数最少的最佳方案。

用三元组(x1,x2,x3)来表示渡河过程中各个状态,其中,x1表示起始岸上修道士个数,x2表示起始岸上野人个数,x3表示小船位置(0——在目的岸,1——在起始岸)。

若问题有解(能渡过河去),则输出一个最佳方案。

用三元组表示渡河过程中的状态,并用箭头指出这些状态之间的迁移:目的状态←…中间状态←…初始状态,若问题无解,则给出“渡河失败”的信息。

2.设计2.1 设计思想(1)数据结构设计逻辑结构设计: 图型结构存储结构设计: 链式存储结构采用这种数据结构的好处:便于采用广度搜索法,得到首先搜索到的边数最少的一条通路,输出一个最佳方案,采用图的邻接表存储结构搜索效率较高。

人工智能原理及其应用——习题答案

人工智能原理及其应用——习题答案

第2章知识表示方法部分参考答案2.8设有如下语句,请用相应的谓词公式分别把他们表示出来:(1)有的人喜欢梅花,有的人喜欢菊花,有的人既喜欢梅花又喜欢菊花。

解:定义谓词P(x):x是人L(x,y):x喜欢y其中,y的个体域是{梅花,菊花}。

将知识用谓词表示为:(∃x )(P(x)→L(x, 梅花)∨L(x, 菊花)∨L(x, 梅花)∧L(x, 菊花))(2) 有人每天下午都去打篮球。

解:定义谓词P(x):x是人B(x):x打篮球A(y):y是下午将知识用谓词表示为:(∃x )(∀y) (A(y)→B(x)∧P(x))(3)新型计算机速度又快,存储容量又大。

解:定义谓词NC(x):x是新型计算机F(x):x速度快B(x):x容量大将知识用谓词表示为:(∀x) (NC(x)→F(x)∧B(x))(4) 不是每个计算机系的学生都喜欢在计算机上编程序。

解:定义谓词S(x):x是计算机系学生L(x, pragramming):x喜欢编程序U(x,computer):x使用计算机将知识用谓词表示为:¬(∀x) (S(x)→L(x, pragramming)∧U(x,computer))(5)凡是喜欢编程序的人都喜欢计算机。

解:定义谓词P(x):x是人L(x, y):x喜欢y将知识用谓词表示为:(∀x) (P(x)∧L(x,pragramming)→L(x, computer))2.9用谓词表示法求解机器人摞积木问题。

设机器人有一只机械手,要处理的世界有一张桌子,桌上可堆放若干相同的方积木块。

机械手有4个操作积木的典型动作:从桌上拣起一块积木;将手中的积木放到桌之上;在积木上再摞上一块积木;从积木上面拣起一块积木。

积木世界的布局如下图所示。

图机器人摞积木问题解:(1) 先定义描述状态的谓词CLEAR(x):积木x上面是空的。

ON(x, y):积木x在积木y的上面。

ONTABLE(x):积木x在桌子上。

修道士和野人问题

修道士和野人问题

修道⼠和野⼈问题 休闲时刻看看神经⽹络⽅⾯的书,发现了修道⼠和野⼈的问题,不禁勾引起我写算法的欲望,曾经的三只⼤⽼虎三只⼩⽼虎过河问题、⼈狼⽺⽩菜过河问题、汉诺塔、哈夫曼等等各种算法瞬间在脑海中约隐约现,修道⼠和野⼈问题我以前好像没有解开,中午吃饭的时候在脑海中重新构造思路,下午耗了点时间把它⼲掉。

(算法不在代码⾥,⽽在思想中;所以尽量不要看我的代码,⽽要仔细分析我写的思路) 题⽬: 设有3个修道⼠和3个野⼈来到河边,打算⽤⼀条船从河的左岸渡到河的右岸。

但该船每次只能装载两个⼈,在任何岸边野⼈的数⽬都不得超过修道⼠的⼈数,否则修道⼠就会被野⼈吃掉。

假设野⼈服从任何⼀种过河安排,请问如何规划过河计划才能把所有⼈都安全地渡过河去。

⾸先考虑总共有(3+1)*(3+1)= 16 种不同的状态(因为左岸可以有0,1,2,3个传教⼠,左岸可以有0,1,2,3个野⼈),所以可以考虑使⽤穷举法。

使⽤如下C#程序语⾔:int MaxNum = 3;for (int monk = MaxNum; monk >= 0; monk--){for (int savage = MaxNum; savage >= 0; savage--){Console.Write("{{" + monk + "," + savage + "},{" + (MaxNum - monk) + "," + (MaxNum - savage) + "}} ");}Console.Write("\n");}⽣成16种状态图↓↓↓↓↓↓↓↓↓↓↓状态图含义:{a,b}:a,左岸修道⼠数量;b,左岸野⼈数量。

--------仅考虑左岸传教⼠和野蛮⼈数量(所有状态图)------------------------{3,3} {3,2} {3,1} {3,0}{2,3} {2,2} {2,1} {2,0}{1,3} {1,2} {1,1} {1,0}{0,3} {0,2} {0,1} {0,0}其中{3,3}是起始状态图;{0,0}是终⽌状态图。

传教士(牧师)与野人问题-模拟人工智能实验_CSDN博客_传教士与野人问题

传教士(牧师)与野人问题-模拟人工智能实验_CSDN博客_传教士与野人问题

传教士(牧师)与野人问题-模拟人工智能实验_结缘缘的博客-CSDN博客_传教士与野人问题题目有n个牧师和n个野人准备渡河但只有一条能容纳c个人的小船为了防止野人侵犯牧师要求无论在何处牧师的人数不得少于野人的人数(除非牧师人数为0) 且假定野人与牧师都会划船试设计一个算法确定他们能否渡过河去若能则给出小船来回次数最少的最佳方案。

实验步骤输入牧师人数(即野人人数) n 小船一次最多载人量c。

输出若问题无解则显示Failed 否则显示Successed输出所有可行方案并标注哪一组是最佳方案。

用三元组(X1, X2, X3)表示渡河过程中的状态。

并用箭头连接相邻状态以表示迁移过程初始状态- 中间状态- 目标状态。

例当输入n 2 c 2时输出221- 200- 211- 010- 021- 000 其中X1表示起始岸上的牧师人数X2表示起始岸上的野人人数X3表示小船现在位置(1表示起始岸0表示目的岸)。

要求写出算法的设计思想和源程序并有用户界面实现人机交互控制台或者窗口都可以进行输入和输出结果如Please input n: 2 Please input c: 2 Optimal Procedure: 221- 200- 211- 010- 021- 000Successed or Failed?: Successed实现代码#include stdio.h #include iostream #include stdlib.h using namespace std;struct State { int Lsavage; int Lgodfather; int Rsavage; int Rgodfather; int boat; //boat at left 0 ; boat at right struct State *States new State[150];struct routesave { int savage; int godfather;struct routesave* routesaves new routesave[150];int godfather, savage, boatnum;void init(State m) { cout 请输入野人和牧师的人数n 以及船的最大载量c endl; int n, c; cin n c; m.Rgodfather n; m.Rsavage n; godfather n, savage n; boatnum c; m.Lgodfather m.Lsavage 0; m.boat 1;void boaloading(int i, int s, int g) { //s个野人和g个传教士if (States[i].boat 0) { routesaves[i].savage s*-1; //左边到右边是负数个野人routesaves[i].godfather g * -1; //左边到右边负数个传教士States[i 1].LsavageStates[i].Lsavage - s; States[i 1].Lgodfather States[i].Lgodfather - g; States[i 1].Rsavage States[i].Rsavage s; States[i 1].Rgodfather States[i].Rgodfather g; States[i 1].boat 1; else{ routesaves[i].savage s; //右边到左边是正数个野人routesaves[i].godfather g; //右边到左边正数个传教士States[i 1].Rsavage States[i].Rsavage-s; States[i 1].RgodfatherStates[i].Rgodfather - g; States[i 1].Lsavage States[i].Lsavage s; States[i 1].Lgodfather States[i].Lgodfather g; States[i 1].boat0;bool checkState(State m) { if (m.Rgodfather 0 m.Rgodfather m.Rsavage) return false; if (m.Lgodfather 0 m.Lgodfatherm.Lsavage) return false; else return true;void showSolution(int i) { cout 问题解决解决路径为endl; for (int c 0; c i; c ) { if (routesaves[c].savage 0) cout 第c 1 步routesaves[c].savage 个野人和routesaves[c].godfather 个传教士乘船去左边endl; else cout 第c 1 步routesaves[c].savage * -1 个野人和routesaves[c].godfather * -1 个传教士乘船去有右边endl; void nextstep(int i) { int c; if (i 150) cout 试探路径过大无法计算; exit(0); for (c 0; c i; c ) /*if the current state is same to previous,retrospect*/ if (States[c].Lsavage States[i].Lsavage States[c].Lgodfather States[i].Lgodfather States[c].Rsavage States[i].Rsavage States[c].Rgodfather States[i].Rgodfather States[c].boat States[i].boat) goto a; if (States[i].Rsavage 0 States[i].Rgodfather 0 States[i].boat 0) { showSolution(i); exit(0); if (States[i].boat 1) { //船在右边for (int s 1; s boatnum s States[i].Rsavage; s ) {//g 0 int g 0; boaloading(i, s, g); if (checkState(States[i 1])) { nextstep(i 1); for (int g 1; g boatnum g States[i].Rgodfather; g ) { //g! 0 for (int s 0; s boatnum - g s States[i].Rsavage s g; s ) { boaloading(i, s, g); if(checkState(States[i 1])) { nextstep(i 1); if (States[i].boat 0) { //船在左边for (int s 1; s boatnum s States[i].Lsavage; s ) {//g 0int g 0; boaloading(i, s, g); if (checkState(States[i 1])) { nextstep(i 1); for (int g 1; g boatnum g States[i].Lgodfather; g ) { //g! 0 for (int s 0; s boatnum - g s States[i].Lsavage s g; s ) { boaloading(i, s, g); if (checkState(States[i 1])) { nextstep(i 1);a:return;void main() { init(States[0]); nextstep(0);实验结果展示。

传教士野人问题

传教士野人问题

问题:野人过河问题属于人工智能学科中的一个经典问题,问题描述如下:有三个牧师(也有的翻译为传教士)和三个野人过河,只有一条能装下两个人的船,在河的任何一方或者船上,如果野人的人数大于牧师的人数,那么牧师就会有危险. 你能不能找出一种安全的渡河方法呢?解答一:一、算法分析先来看看问题的初始状态和目标状态,假设和分为甲岸和乙岸:初始状态:甲岸,3野人,3牧师;乙岸,0野人,0牧师;船停在甲岸,船上有0个人;目标状态:甲岸,0野人,0牧师;乙岸,3野人,3牧师;船停在乙岸,船上有0个人;整个问题就抽象成了怎样从初始状态经中间的一系列状态达到目标状态。

问题状态的改变是通过划船渡河来引发的,所以合理的渡河操作就成了通常所说的算符,根据题目要求,可以得出以下5个算符(按照渡船方向的不同,也可以理解为10个算符):渡1野人、渡1牧师、渡1野人1牧师、渡2野人、渡2牧师算符知道以后,剩下的核心问题就是搜索方法了,本文采用深度优先搜索,通过一个FindNext(…)函数找出下一步可以进行的渡河操作中的最优操作,如果没有找到则返回其父节点,看看是否有其它兄弟节点可以扩展,然后用Process(…)函数递规调用FindNext(…),一级一级的向后扩展。

搜索中采用的一些规则如下:1、渡船优先规则:甲岸一次运走的人越多越好(即甲岸运多人优先),同时野人优先运走;乙岸一次运走的人越少越好(即乙岸运少人优先),同时牧师优先运走;2、不能重复上次渡船操作(通过链表中前一操作比较),避免进入死循环;3、任何时候河两边的野人和牧师数均分别大于等于0且小于等于3;4、由于只是找出最优解,所以当找到某一算符(当前最优先的)满足操作条件后,不再搜索其兄弟节点,而是直接载入链表。

5、若扩展某节点a的时候,没有找到合适的子节点,则从链表中返回节点a的父节点b,从上次已经选择了的算符之后的算符中找最优先的算符继续扩展b。

二、基本数据结构仔细阅读问题,可以发现有些基本东西我们必须把握,例如:每时刻河两岸野人牧师各自的数目、船的状态、整个问题状态。

传教士野人问题

传教士野人问题

问题:野人过河问题属于人工智能学科中的一个经典问题,问题描述如下:有三个牧师(也有的翻译为传教士)和三个野人过河,只有一条能装下两个人的船,在河的任何一方或者船上,如果野人的人数大于牧师的人数,那么牧师就会有危险. 你能不能找出一种安全的渡河方法呢?解答一:一、算法分析先来看看问题的初始状态和目标状态,假设和分为甲岸和乙岸:初始状态:甲岸,3野人,3牧师;乙岸,0野人,0牧师;船停在甲岸,船上有0个人;目标状态:甲岸,0野人,0牧师;乙岸,3野人,3牧师;船停在乙岸,船上有0个人;整个问题就抽象成了怎样从初始状态经中间的一系列状态达到目标状态。

问题状态的改变是通过划船渡河来引发的,所以合理的渡河操作就成了通常所说的算符,根据题目要求,可以得出以下5个算符(按照渡船方向的不同,也可以理解为10个算符):渡1野人、渡1牧师、渡1野人1牧师、渡2野人、渡2牧师算符知道以后,剩下的核心问题就是搜索方法了,本文采用深度优先搜索,通过一个FindNext(…)函数找出下一步可以进行的渡河操作中的最优操作,如果没有找到则返回其父节点,看看是否有其它兄弟节点可以扩展,然后用Process(…)函数递规调用FindNext(…),一级一级的向后扩展。

搜索中采用的一些规则如下:1、渡船优先规则:甲岸一次运走的人越多越好(即甲岸运多人优先),同时野人优先运走;乙岸一次运走的人越少越好(即乙岸运少人优先),同时牧师优先运走;2、不能重复上次渡船操作(通过链表中前一操作比较),避免进入死循环;3、任何时候河两边的野人和牧师数均分别大于等于0且小于等于3;4、由于只是找出最优解,所以当找到某一算符(当前最优先的)满足操作条件后,不再搜索其兄弟节点,而是直接载入链表。

5、若扩展某节点a的时候,没有找到合适的子节点,则从链表中返回节点a的父节点b,从上次已经选择了的算符之后的算符中找最优先的算符继续扩展b。

二、基本数据结构仔细阅读问题,可以发现有些基本东西我们必须把握,例如:每时刻河两岸野人牧师各自的数目、船的状态、整个问题状态。

人工智能:野人与修道士问题

人工智能:野人与修道士问题

野人与修道士问题(Missionaries-and-Cannibals Problem )[修道士与野人问题]:三个野人与三个传教士来到河边,打算乘一只船从右岸渡到左岸去,该船的最大负载能力为两个人。

在任何时候,如果野人人数超过传教士人数,那么野人就会把传教士吃掉。

用状态空间法表示修道士与野人问题并设计编写计算机程序求问题的解。

问题分析:从上图可知,修道士、野人和船一共有六种可能,M L 、C L 、B L 、M R 、C R 、B R 。

可以表示为q =(M ,C ,B ),其中m 表示修道士的数目(0、1、2、3)、c 表示野人的数目(0、1、2、3)、b 表示船在左岸(1)或右岸(0)。

1、定义状态的描述形式:(m ,c ,b )2、表示所有可能的状态,并确定初始状态集和目标状态集:s0(3,3,1) s8(1,3,1) s16(3,3,0) s24(1,3,0)s1(3,2,1) s9(1,2,1) s17(3,2,0) s25(1,2,0)s2(3,1,1) s10(1,1,1) s18(3,1,0) s26(1,1,0)s3(3,0,1) s11(1,0,1) s19(3,0,0) s27(1,0,0)s4(2,3,1) s12(0,3,1) s20(2,3,0) s28(0,3,0)s5(2,2,1) s13(0,2,1) s21(2,2,0) s29(0,2,0)s6(2,1,1) s14(0,1,1) s22(2,1,0) s30(0,1,0)s7(2,0,1) s15(0,0,1) s23(2,0,0) s31(0,0,0)初始状态:(3,3,1)目标状态:(0,0,0)3、定义算符:L ij :把i 个修道士,j 个野人从河的左岸送到右岸R ij :把i 个修道士,j 个野人从河的右岸送到左岸整个问题就抽象成了怎样从初始状态经中间的一系列状态达到目标状态。

问修道士M野 人C 左L 右R题状态的改变是通过划船渡河来引发的,所以合理的渡河操作就成了通常所说的算符,根据题目要求,可以得出以下5个算符(按照渡船方向的不同,也可以理解为10个算符):渡1野人、渡1牧师、渡1野人1牧师、渡2野人、渡2牧师即:L01或R01,L10或R10,L11或R11,L02或R02,L20或R204、状态空间图:5、设计编写计算机程序求问题的解:算法:在应用状态空间表示和搜索方法时,用(M,C,B)来表示状态描述,其中M和C分别表示在左岸的传教士与野人数。

修道士与野人问题

修道士与野人问题

6.修道士与野人问题这是一个古典问题。

假设有n个修道士和n个野人准备渡河,但只有一条能容纳c人的小船,为了防止野人侵犯修道士,要求无论在何处,修道士的个数不得少于野人的人数(除非修道士个数为0)。

如果两种人都会划船,试设计一个算法,确定他们能否渡过河去,若能,则给出一个小船来回次数最少的最佳方案。

要求:(1)用一个三元组(x1,x2,x3)表示渡河过程中各个状态。

其中,x1表示起始岸上修道士个数,x2表示起始岸上野人个数,x3表示小船位置(0——在目的岸,1——在起始岸)。

例如(2,1,1)表示起始岸上有两个修道士,一个野人,小船在起始岸一边。

采用邻接表做为存储结构,将各种状态之间的迁移图保存下来。

(2)采用广度搜索法,得到首先搜索到的边数最少的一条通路。

(3)输出数据若问题有解(能渡过河去),则输出一个最佳方案。

用三元组表示渡河过程中的状态,并用箭头指出这些状态之间的迁移:目的状态←…中间状态←…初始状态。

若问题无解,则给出“渡河失败”的信息。

(4)求出所有的解。

1.需求分析有n个修道士和n个野人准备渡河,但只有一条能容纳c人的小船,为了防止野人侵犯修道士,要求无论在何处,修道士的个数不得少于野人的人数,否则修道士就会有危险,设计一个算法,确定他们能否渡过河去,若能,则给出一个小船来回次数最少的最佳方案。

用三元组(x1,x2,x3)来表示渡河过程中各个状态,其中,x1表示起始岸上修道士个数,x2表示起始岸上野人个数,x3表示小船位置(0——在目的岸,1——在起始岸)。

若问题有解(能渡过河去),则输出一个最佳方案。

用三元组表示渡河过程中的状态,并用箭头指出这些状态之间的迁移:目的状态←…中间状态←…初始状态,若问题无解,则给出“渡河失败”的信息。

2.设计2.1 设计思想(1)数据结构设计逻辑结构设计: 图型结构存储结构设计: 链式存储结构采用这种数据结构的好处:便于采用广度搜索法,得到首先搜索到的边数最少的一条通路,输出一个最佳方案,采用图的邻接表存储结构搜索效率较高。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档