农夫过河
农夫过河演示文稿

图论问题
• 将各个顶点与人狼羊菜这一点的距离标示 在图顶处,于是可以看到有两种最迅速而 且安全的运送方案 • (1)人狼羊菜,狼菜,人狼菜,狼,人狼 羊,羊,人羊,空; • (2)人狼羊菜,狼菜,人狼菜,菜,人羊 菜,羊,人羊,空。 • 每种方案都要渡河七次。
搜索问题
FWDC
F W
DC
F WG C
• 去掉不可能的状态:狼羊菜,羊菜,狼羊 • 与之对应的三种状态也不可能出现,所以剩下10 种可能的情形。
• 将这十种情形看作是点,只有在两种状态可以相 互转变的时候,在他们之间建立一条边线。 • 至此,整个题目就变成了{人狼羊菜}=>。。。=》 {}的过程;也就是从图中找出从“人狼羊菜”到 “空”的最短路径。
WG C F F W
G C F
W G
C F
WG C
F W G
C
F WG C
W F G
C F WG
C F
W G C
F WG
C
F W G
C
F W
G C
F W G C
F WG C
F W G
C
G C F W F WG
C F W
G C F
WG C F W
G C F
W G C
F W
G C
F WG C
F W
G C
G F W C F WG C
Illegal State
Repeated State
Goal State
F WD C
F
W D C
最初状态 人带羊到对岸 人独自返回 人带狼到对岸
W F D
C F
W D
C
F W D
农夫过河问题状态空间表示

逻辑学教授的3个得意门生ABC,前一晚在酒吧喝多了,结果第二天3人集体迟到。
教授说:“作为对你们迟到的惩罚,你们3人必须比其他同学多做一道作业,完成了这道作业才可以离开教室。
”这道附加的作业是一道帽子题,教授给每人戴了顶帽子,帽子不是红色就是白色,不是白色就是红色。
每人都能看见其他2人帽子的颜色,却不能看见自己帽子的颜色。
每人都看到其他2人帽子的颜色后,每思考5分钟为一轮,谁猜出自己帽子的颜色了就可以说出来并离开。
教授还说:“你们3人中至少有1人戴了红色帽子。
”第一轮下来,A说:“我没猜出来。
”B说“我也没猜出来”C说:“我也猜不出。
”第二轮下来,还是没人能猜出自己帽子的颜色。
第三轮,3人都猜出了自己帽子的颜色。
问:ABC三人头顶都是什么颜色的帽子?然后用谓词逻辑写出推理过程。
最一般合一及归结反演相关已知w={P(f(x,g(A,y)),z), P(f(x,z),z),求MGU令δ0=ε,w0=w,因w中含有两个表达式,因此δ0不是最一般合一差异集D0={g(A,y)/z}δ1=δ0ºD0={g(A,y)/z}w1={P(f(x,g(A,y)),g(A,y)), P(f(x,g(A,y)),g(A,y))w1中仅含有一个表达式,所以δ1就是最一般合一。
证明G是否是F1、F2的逻辑结论。
F1:(∀x)(P(x)→(Q(x)∧R(x)))F2:(∃x)(P(x)∧S(x))G: (∃x)(S(x)∧R(x))F1: ¬P(x)∨(Q(x)∧R(x)) ⇒(¬P(x)∨Q(x)) ∧(¬P(x)∨R(x))F2: P(x)∧S(x)¬G: ¬(∃x)(S(x)∧R(x)) ⇒ (∀x)(¬(S(x)∧R(x))) ⇒¬S(x)∨¬R(x)子句集:1 ¬P(x)∨Q(x)2 ¬P(x)∨R(x)3 P(x)4 S(x)5 ¬S(x)∨¬R(x)其中2与3规约,4与5归结,其结果再归结得到空子句,证明G是F1与F2的结论。
课程设计农夫过河

课程设计农夫过河一、教学目标本章节的教学目标包括以下三个方面:1.知识目标:学生能够理解并掌握“农夫过河”问题的背景、条件和目标,了解相关的数学知识,如线性方程、不等式等。
2.技能目标:学生能够运用所学的数学知识,通过分析和逻辑推理,找到解决问题的方法,并能够进行有效的沟通和合作。
3.情感态度价值观目标:学生能够培养问题解决的兴趣和自信心,培养团队合作和沟通的能力,培养对数学学科的积极态度。
二、教学内容本章节的教学内容主要包括以下几个部分:1.引入“农夫过河”问题的背景和条件,引导学生了解问题的目标和意义。
2.引导学生学习相关的数学知识,如线性方程、不等式等,并通过例题和练习题进行巩固。
3.引导学生运用所学的数学知识,分析和解决“农夫过河”问题,寻找最优解法。
4.通过小组讨论和展示,培养学生的团队合作和沟通能力。
三、教学方法本章节的教学方法主要包括以下几种:1.讲授法:教师通过讲解和演示,引导学生理解和掌握相关的数学知识和解决问题的方法。
2.讨论法:教师学生进行小组讨论,鼓励学生提出问题、分享思路和解决方案。
3.案例分析法:教师提供具体的案例,引导学生运用所学的数学知识进行分析和解决。
4.实验法:教师引导学生进行实验操作,通过实践来加深对数学知识的理解和应用。
四、教学资源本章节的教学资源主要包括以下几种:1.教材:教师准备相关的数学教材,提供理论知识的学习和练习题的练习。
2.参考书:教师提供相关的参考书籍,供学生进一步深入学习和探索。
3.多媒体资料:教师准备相关的多媒体资料,如图片、视频等,用于辅助讲解和演示。
4.实验设备:教师准备相关的实验设备,供学生进行实验操作和实践。
五、教学评估本章节的教学评估主要包括以下几种方式:1.平时表现:教师通过观察和记录学生在课堂上的参与程度、提问回答等情况,评估学生的学习态度和表现。
2.作业:教师通过布置和批改相关的作业,评估学生对知识的理解和应用能力。
3.考试:教师通过安排章节考试或者小测验,评估学生对知识掌握的程度和问题解决的能力。
农夫过河问题

农夫过河问题
一、先分析农夫过河的情景:1.他走到了小桥上,遇见了大象;2.他看见小桥很窄,不能通过大象,于是下来,又看见了小兔子;3.小兔子让他再回去把自己带来的萝卜给小猴子送去;4.他想了想,就决定去找乌龟帮忙。
二、农夫为什么要这样做?我们可以用图中所示的几种方法来解答:(1)如果你是农夫,你会怎么办呢?(2)我们在学习时也常常有这样的问题,面对某个复杂的问题,总是从多角度考虑它,然后得出最佳的解决方案。
比如我们要学好数学,需要同学之间互相讨论交流,取长补短,共同进步。
三、根据刚才提供的信息和已经确立的条件,你认为哪些条件更重要?请写出两点理由并说明原因。
四、结合生活实际谈谈应该怎样正确处理人与人之间的关系。
农夫携物过河程序

题目内容:有一农夫要将自己的羊、蔬菜和狼等3件物品运过河。
但农夫过河时所用的船每次最多只能装其中的一件物品,而这3件物品之间又存在一定的制约关系:羊不能单独和狼以及不能和蔬菜在一起,因为狼要吃羊,羊也能吃蔬菜。
试构造出问题模式以编程实现这一问题的求解。
1、问题分析和任务定义:根据对象的状态分为过河(1)和不过河(0),此对象集合就构成了一个状态空间。
问题就是在这个状态空间内搜索一条从开始状态到结束状态的安全路径。
显然,其初始状态为四对象都不过河,结束状态为四对象全部过河。
这里用无向图来处理,并采用邻接矩阵存储。
对于农夫,狼,羊,蔬菜组成一个4位向量,即图的顶点(F,W,S,V),状态空间为16,初始状态为(0000),目标为(1111)。
解决问题的方法是,找到所有的安全状态,并在其中搜索出一条(0000)到(1111)的路径。
对当前对象是否安全的判断,若当农夫与羊不在一起时,狼与羊或羊与蔬菜在一起是不安全的,其他情况是安全的。
搜索一条可行路径时,采用深度优先搜索DFS_path,每个时刻探索一条路径,并记录访问过的合法状态,一直向前探视,直到走不通时回溯。
显然,应该用数组来保存访问过的状态,以便回溯。
显然农夫每次状态都在改变,最多也就能带一件东西过河,故搜索条件是,在顶点(F,W,S,V)的转换中,狼,羊,蔬菜三者的状态不能大于一个,即只有一个发生改变或者都不变。
①数据的输入形式和输入值的范围:本程序不需要输入数据,故不存在输入形式和输入值的范围。
②结果的输出形式:在屏幕上显示安全状态的转换,即一条安全路径。
2、数据结构的选择概要设计⑴数据结构的选择:本程序采用无向图处理。
#define MaxNumVertices 10 //最大顶点数typedef struct //图的顶点类型{int Farmer,Wolf,Sheep,Veget;//存储农夫,狼,羊,蔬菜的状态}VexType;typedef struct//图的各项信息{int VertexNum,CurrentEdges; //图的当前顶点数和边数VexType VerticesList[MaxNumVertices]; //顶点向量(代表顶点)int Edge[MaxNumVertices][MaxNumVertices];//邻接矩阵//用于存储图中的边,其矩阵元素个数取决于顶点个数,与边数无关}AdjGraph;⑵为了实现上述程序的功能,需要:①生成所有安全的图的顶点;②查找顶点的位置;③判断目前(F,W,S,V)是否安全,安全返回1,否则返回0;④判断顶点i和顶点j之间是否可转换,可转换返回真,否则假;⑤深度优先搜索从u到v的简单路径;⑥输出从u到v的简单路径,即顶点序列中不重复出现的路径。
农夫过河问题

问题一:农夫,狐狸,鹅和麦粒过河问题。
他们都在河的左岸,现在要全部到对岸去,农夫有一条船,过河时,除农夫外,船上至多能载一样东西,狐狸要吃鹅,鹅要吃麦粒,除非农夫在那里。
规划出确保全部安全的过河方案。
解:用四元组(农夫,狐狸,鹅,麦粒)表示状态,其中每个元素都可为0或1。
0表示在左岸,用1表示在右岸。
用四元组(f、w、s、g)表示状态, f 代表农夫,w 代表狐狸,s 代表鹅,g 代表麦粒
初始状态S0:(0,0,0,0)目标状态:(1,1,1,1)
不合法状态有:(1,0,0,*),(1,*,0,0),(0,1,1,*),(0,*,1,1)
操作集F={p1,p2,p3,p4,q0,q1,q2,q3 }
首先分析如图所示:
操作符条件动作
p1 f=0,w=0f=1,w=1
s和g相异
p2 f=0,s=0 f=1,s=1
p3 f=0,g=0 f=1,g=1
w和s相异
q0 f=1 f=0
s和g相异
w和s相异
q1 f=1,w=1f=0,w=0
s和g相异
q2 f=1,s=1 f=0,s=0
q3 f=1,g=1 f=0,g=0
w和s相异
所以,方案有两种:
p2→ q0 → p3→ q2 → p2 → q0 → p2 p2→ q0 → p1→ q2 → p3→ q0→ p2。
农夫过河报告(最终版)

农夫过河报告(最终版).12.29Administrator组员:李琦、郑鸿飞、王琅辉、张育博这最起码是一个报告,虽然我摘要农夫过河问题是应用广度优先搜索和深度优先搜索的典型问题,但这里我们应用了简单的数组,通过层层筛选的手段也解决了同样的问题,其中用到了部分广度优先搜索的思想。
前言农夫过河问题描述:一个农夫带着—只狼、一只羊和—棵白菜,身处河的南岸。
他要把这些东西全部运到北岸。
他面前只有一条小船,船只能容下他和—件物品,另外只有农夫才能撑船。
如果农夫在场,则狼不能吃羊,羊不能吃白菜,否则狼会吃羊,羊会吃白菜,所以农夫不能留下羊和白菜自己离开,也不能留下狼和羊自己离开,而狼不吃白菜。
请求出农夫将所有的东西运过河的方案。
正文1.问题抽象和数据组织农夫过河问题应该应用图的广度优先遍历或者深度优先遍历,但这里我们仅使用简单的线性表——数组,通过多重的条件限制,达成目的。
这里我们同样用0和1代表农夫、狼、羊、白菜在左岸还是在右岸,并规定0在左,1在右,我们的目的便是从0000通过一系列变换到1111。
2.农夫过河算法源代码#include <stdio.h>#define MAX 16typedef struct FWSV{i nt farmer;i nt wolf;i nt sheep;i nt vegetable;}Item;//函数原型//操作:筛选符合条件的安全的数组成员//操作前:无//操作后:返回安全数组的指针void screen(void);//操作:判断下一个数应该取安全数组中那个数//操作前: 传递一个结构体数组成员//操作后:返回另一个结构体数组指针Item * judge(Item Fwsv);Item safe[MAX];int k = 0; //用于计数safe[]中的总数int main (void){s creen();I tem * next;I tem first,second,end;f irst = safe[0];e nd = safe[k];p rintf("first:0000\n");n ext = judge(first);for (int count = 0;count <= 6;count++){if (next->farmer + next->wolf + next->sheep + next->vegetable != 0){second = *next;next = judge(second);}elsenext++;}printf("end:1111\n");r eturn 0;}void screen(void){i nt f = 0,w = 0,s = 0,v = 0;f or(f = 0;f < 2;f++){for(w = 0;w < 2;w++){for(s = 0;s < 2;s++){for(v = 0;v < 2;v++){if (!(f != s && (s == w || s == v))){safe[k].farmer = f;s afe[k].wolf = w;s afe[k].sheep = s;safe[k].vegetable = v;k++;}}}}}}Item * judge(Item Fwsv){I tem * next;Item compare[4];n ext = compare;i nt x1 = 0;i nt sum = 0;i f (Fwsv.farmer == 0){for (int x = 0;x < k;x++){//把出现过的置零操作if(safe[x].farmer == Fwsv.farmer && safe[x].wolf == Fwsv.wolf && safe[x].sheep == Fwsv.sheep && safe[x].vegetable == Fwsv.vegetable ){safe[x].farmer = 0;safe[x].wolf = 0;safe[x].sheep = 0;safe[x].vegetable = 0;}//筛选出农夫状态值与之前相反的1变0 0变1if(safe[x].farmer == 1 && (safe[x].farmer + safe[x].wolf + safe[x].sheep + safe[x].vegetable != 4 )) {compare[x1] = safe[x];x1++;}}for (int x2 = 0;x2 < 4;x2++){//删除状态值与农夫不同但是改变了的sum = Fwsv.farmer + Fwsv.wolf + Fwsv.sheep + Fwsv.vegetable;if ((Fwsv.farmer != Fwsv.wolf && compare[x2].wolf != Fwsv.wolf)||(Fwsv.farmer != Fwsv.sheep && compare[x2].sheep != Fwsv.sheep)|| (Fwsv.farmer != Fwsv.vegetable && compare[x2].vegetable != Fwsv.vegetable)|| (Fwsv.farmer != Fwsv.vegetable && compare[x2].vegetable != Fwsv.vegetable)){compare[x2].farmer = 0;compare[x2].wolf = 0;compare[x2].sheep = 0;compare[x2].vegetable = 0;}sum+=2;//对和的限制if(compare[x2].farmer + compare[x2].wolf + compare[x2].sheep + compare[x2].vegetable != sum){compare[x2].farmer = 0;compare[x2].wolf = 0;compare[x2].sheep = 0;compare[x2].vegetable = 0;}}printf("-----------------------------------------\n");for(int x3 = 0;x3 < 4;x3++){if (compare[x3].farmer + compare[x3].wolf + compare[x3].sheep + compare[x3].vegetable != 0){printf("上数与:%d%d%d%d相连\n",c ompare[x3].farmer,compare[x3].wolf,c ompare[x3].sheep,compare[x3].vegetabl );}}}i f (Fwsv.farmer == 1){for (int y = 0;y < k;y++){if(safe[y].farmer == Fwsv.farmer && safe[y].wolf == Fwsv.wolf && safe[y].sheep == Fwsv.sheep && safe[y].vegetable == Fwsv.vegetable ){safe[y].farmer = 0;safe[y].wolf = 0;safe[y].sheep = 0;safe[y].vegetable = 0;}if(safe[y].farmer == 0 && (safe[y].farmer + safe[y].wolf + safe[y].sheep + safe[y].vegetable != 0 )) {compare[x1] = safe[y];x1++;}}for (int x2 = 0;x2 < 4;x2++){sum = Fwsv.farmer + Fwsv.wolf + Fwsv.sheep + Fwsv.vegetable;if ((Fwsv.farmer != Fwsv.wolf && compare[x2].wolf != Fwsv.wolf)||(Fwsv.farmer != Fwsv.sheep && compare[x2].sheep != Fwsv.sheep)|| (Fwsv.farmer != Fwsv.vegetable && compare[x2].vegetable != Fwsv.vegetable)|| (Fwsv.farmer != Fwsv.vegetable && compare[x2].vegetable != Fwsv.vegetable)){compare[x2].farmer = 0;compare[x2].wolf = 0;compare[x2].sheep = 0;compare[x2].vegetable = 0;}}printf("-----------------------------------------\n");for(int x3 = 0;x3 < 4;x3++){if (compare[x3].farmer + compare[x3].wolf + compare[x3].sheep + compare[x3].vegetable != 0){printf("上数与:%d%d%d%d相连\n",compare[x3].farmer,compare[x3].wolf,com pare[x3].sheep,compare[x3].vegetable );}}r eturn next;}3.算法功能说明和流程描述首先我们定义了一个结构体Itemtypedef struct FWSV{int farmer;int wolf;int sheep;int vegetable;}Item;Item中包含了农夫(farmer),狼(wolf),羊(sheep),白菜(vegetable),用来表示农夫、狼、羊、白菜的状态,并作出规定当为0的时候表示在左岸,当为1的时候表示在右岸,我们的目标便是从0000的状态到1111的状态。
农夫过河问题

农夫过河问题1. 题目描述:一个农夫带着一只狼,一只羊和一筐菜,欲从河的左岸坐船到右岸,由于船太小,农夫每次只能带一样东西过河,并且没有农夫看管的话,狼会吃掉羊,羊会吃菜。
设计一个方案,使农夫可以无损失的过河2. 题目分析:假设人、狼、菜、羊都在河岸a,要到b 河岸去。
题中的食物链关系为: 菜→羊→狼 所以,第一次人只能带羊到b 河岸; 回到a 时,人不能再将刚带过来的羊带回去,所以人是空手回到a 的; 在a 河岸,人有两个选择选择一:(1) 带狼到b,人再回到a 时,因为不能把狼和羊同时留下,所以只能带走羊;AA 羊 A B羊狼 菜 怎么办呢 B 羊 B 狼 菜 菜 狼(2) 再次回到a 后,人再到b 时,不能把羊和菜同时留下,所以只能带走菜; (3) 再次回到a 时,因为狼和菜可以同时留下,所以优先选择空手过河;到a 后发现只剩下羊,所以带羊过河。
选择二:(1) 带菜到b,人再回到a 时,因为不能把菜和羊同时留下,所以只能带走羊;(2) 再次回到a 后,人再到b 时,不能把羊和狼同时留下,所以只能带走狼;狼 羊 羊 A菜 B 羊 狼 A B 狼 AB 狼 AB 羊菜 菜 菜(3) 再次回到a 时,因为狼和菜可以同时留下,所以优先选择空手过河;到a 后发现只剩下羊,所以带羊过河。
解:用四元组S 表示状态,即S =(L ,J ,M ,N )其中L :农夫 J :狼 M :羊 N :菜用0表示在左岸岸,1表示在右岸,即S=(0,0,0,0) 目标G =(1,1,1,1)定义操作符L (i )表示农夫带东西到右岸:i=0 农夫自己到右岸;i=1 农夫带狼到右岸;i=2 农夫带羊到右岸;i=3 农夫带菜到右岸;定义操作符R (i )表示农夫带东西到左岸:i=0 农夫自己到左岸;i=1 农夫带狼到左岸;i=2 农夫带羊到左岸;i=3 农夫带菜到左岸;约束状态如下:(1,0,0,1)狼、羊在左岸;(1,1,0,0)羊、菜在左岸;(0,1,1,0)狼、羊在右岸;(0,0,1,1)羊、菜在右岸;(1,0,0,0)狼、羊、菜在左岸;(0,1,1,1)狼、羊、菜在右岸;羊 A B狼 菜。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
农夫过河问题——程序设计
(2009-06-05 13:38:22)
标签:分类:
一、问题需求分析
一个农夫带着一只狼、一只羊和一棵白菜,身处河的南岸。
他要把这些东西全部运到北岸。
问题是他面前只有一条小船,船小到只能容下他和一件物品,另外只有农夫能撑船。
另外,因为狼能吃羊,而羊爱吃白菜,所以农夫不能留下羊和白菜或者狼和羊单独在河的一边,自己离开。
请问农夫该采取什么方案才能将所有的东西运过河呢?
二、算法选择
求解这个问题的最简单的方法是一步一步进行试探,每一步都搜索所有可能的选择,对前一步合适的选择再考虑下一步的各种方案。
用计算机实现上述求解的搜索过程可以采用两种不同的策略:一种是广度优先(breadth_first) 搜索,另一种是深度优先(depth_first) 。
广度优先:
u 广度优先的含义就是在搜索过程中总是首先搜索下面一步的所有可能状态,然后再进一步考虑更后面的各种情况。
u 要实现广度优先搜索,一般都采用队列作为辅助结构。
把下一步所有可能达到的状态都列举出来,放在这个队列中,然后顺序取出来分别进行处理,处理过程中把再下一步的状态放在队列里……。
u 由于队列的操作遵循先进先出的原则,在这个处理过程中,只有在前一步的所有情况都处理完后,才能开始后面一步各情况的处理。
三、算法的精化
要模拟农夫过河问题,首先需要选择一个对问题中每个角色的位置进行描述的方法。
一个很方便的办法是用四位二进制数顺序分别表示农夫、狼、白菜和羊的位置。
例如用0表示农夫或者某东西在河的南岸,1表示在河的北岸。
因此整数5(其二进制表示为0101) 表示农夫和白菜在河的南岸,而狼和羊在北岸。
四、算法的实现
完成了上面的准备工作,现在的问题变成:
从初始状态二进制0000(全部在河的南岸) 出发,寻找一种全部由安全状态构成的状态序列,它以二进制1111(全部到达河的北岸) 为最终目标,并且在序列中的每一个状态都可以从前一状态通过农夫(可以带一样东西)划船过河的动作到达。
为避免不必要的瞎费功夫,要求在序列中不应该出现重复的状态。
为了实现广度优先搜索,算法中需要使用了一个整数队列moveTo,它的每个元素表示一个可以安全到达的中间状态。
另外还需要一个数据结构记录已被访问过的各个状态,以及已被发现的能够到达当前这个状态的路径。
由于在这个问题的解决过程中需要列举的所有状态(二进制0000 ~ 1111)一共16种,所以可以构造一个包含16个元素的整数顺序表来满足以上的要求。
用顺序表的第i个元素记录状态i是否已被访问过,若已被访问过则在这个顺序表元素中记入前驱状态值,算法中把这个顺序表叫做route。
route的每个分量初始化值均为-1,每当我们在队列中加入一个新状态时,就把顺序表中以该状态作下标的元素的值改为达到这个状态的路径上前一状态的下标值。
route的一个元素具有非负值表示这个状态已访问过,或是正被考虑。
最后我们可以利用route顺序表元素的值建立起正确的状态路径。
五、程序代码
n");
else
{
queue->q[queue->r] = x;
queue->r = (queue->r + 1) % queue->MAXNUM;
}
}
void deQueue_seq(PSeqQueue queue)
n");
else
queue->f = (queue->f + 1) % queue->MAXNUM;
}
DataType frontQueue_seq(PSeqQueue queue)
{
if (queue->f == queue->r)
printf("Empty Queue.\n");
else
return (queue->q[queue->f]);
}
n");
//问题无解
}
六、测试结果
程序输出按相反的变化方向输出的,真实的情况应该是从0、9、……、15变化的。
七、总结和体会
这个程序还有很大的改进空间,首先是人性化方面的设计,这个程序最终的输出结果是用10进制的,而我们需要知道的应该是二进制的结果,所以应该直接把结果输出为二进制,还要按开始到最终状态的排序输出。
还有一种更为人性化的设计,就是把对应的每个二进制代码代表的含义直接用中文表示出来,这样的结果更直观,方便用户使用。
例如:0000时,程序输出:所有的物品都在南岸。
后面的一个状态是9(1001),程序输出:农夫和羊到了北岸。
通过这个程序的学习,很受启发,明白了如何用计算机解决实际生活中的问题。
刚开始接到这个题目时,感觉到相当困难,因为这种题以前是考验我们的IQ用的,现在没想到要用计算机来解决,而且计算机又没有思想,怎样让它想问题,实现我们需要的功能。
原来,可以把实际的问题转变为数学模型,通过计算机超强悍的循环功能和强大的数据处理能力,把所有可能的结果都算出来,然后用约束项来对这些结果进行筛选,然后把结果用数学格式来输出,让问题得以求解。
这个程序的设计方法比较巧妙的地方是数学建模,即每个角色的位置进行描述的方法:用四位二进制数顺序分别表示农夫、狼、白菜和羊的位置。
例如用0表示农夫或者某东西在河的南岸,1表示在河的北岸。
因此整数5(其二进制表示为0101) 表示农夫和白菜在河的南岸,而狼和羊在北岸。
这个方法令人拍案叫绝,不得不佩服人类的智慧。