(状态机)狼羊菜过河的程序
农夫过河问题(C++编写)

cout<<" **
------------------------
**\n";
cout<<" **
|
农夫过河问题
|
**\n";
cout<<" **
------------------------
**\n";
cout<<"
****************************************************************************\n";
1、问题描述
从前,一个农夫带着一只狼,一只羊和一棵白菜要河(注意该狼被农夫训服了,但还会 吃羊)。他要将所有东西安全的带到河的对岸,不幸的是河边只有一条船,只能装下农夫和 他的一样东西,并且农夫必须每次都随船过,因为只有他能撑船。在无人看管的情况下,狼 要吃羊,羊要吃白菜,因此,农夫不能在河的某边岸上单独留下狼和羊,也不能单独留下羊 和白菜。那么农夫如何才能使三样东西平安过河呢?
3)、如果上两个条件都不满,则可执行运输的动作,但每次都应考虑,该运 输情况以前是否执行过(即两岸以及船上的东西以时四者各自的状态,并递归的进行下一次运载。
5、系统测试
6、经验总结
解决实际问题时,应先分析实际问题,找出实际问题的所有约束条件, 然后对问题进行数学模型的抽象化,抓主要因素,省去一些不需要的因素,将其 抽象为数学问题,然后再从整体上设计算法,搭建程序的框架,最后一步步完善 细节,这样做,会使本来毫无头绪的问题变得清晰起来。
if (a[ferryTimes][i] == a[ferryTimes][3]) {
人狼羊菜渡河问题(含Matlab程序)

人、狼、羊、菜安全渡河问题安全渡河问题又称作“人狼羊菜”问题,其具体描述为:一个人带着一条狼、一只羊、一筐白菜过河但由于船太小,人一次只能带一样东西乘船过河。
狼和羊、羊和白菜不能单独留在同岸,否则羊或白菜会被吃掉。
该问题可使用图论中的最短路算法进行求解。
问题分析根据题意,人不在场时,狼要吃羊,羊要吃菜,因此,人不在场时,不能将狼与羊、羊与菜留在河的任一岸。
可用四维向量v=(m,n,p,q)来表示状态,m表示人,n代表狼,p代表羊,q代表白菜,且m,n,p,q ∈{0,1},0代表在对岸,1代表在此岸。
例如,状态(0,1,1,0)表示人和菜在对岸,而狼和羊在此岸,这时人不在场,狼要吃羊,因此,这个状态是不可行的。
通过穷举法将所有可行的状态列举出来,可行的状态有(1,1,1,1),(1,1,1,0),(1,1,0,1),(1,0,1,1),(1,0,1,0),(0,1,0,1),(0,1,0,0),(0,0,1,0),(0,0,0,1),(0,0,0,0)。
可行状态共有十种。
每一次的渡河行为改变现有的状态。
现构造赋权图G=(V,E,W),其中顶点集V={v1,…, v10}中的顶点(按照上面的顺序编号)分别表示上述10个可行状态,当且仅当对应的两个可行状态之间存在一个可行转移时两顶点之间才有边连接,并且对应的权重取为1,当两个顶点之间不存在可行转移时,可以把相应的权重取为∞。
因此问题变为在图G中寻找一条由初始状态(1,1,1,1)出发,经最小次数转移到达最终状态(0,0,0,0)的转移过程,即求从状态(1,1,1,1)到状态(0,0,0,0)的最短路径。
该问题难点在于计算邻接矩阵,由于摆渡一次就改变现有状态,为此再引入一个四维状态转移向量,用它来反映摆渡情况。
用1表示过河,0表示未过河。
例如,(1,1,0,0)表示人带狼过河。
状态转移只有四种情况,用如下向量表示:(1,0,0,0),(1,1,0,0),(1,0,1,0),(1,0,0,1)现在规定状态向量与转移向量之间的运算为0+0=0,1+0=1,0+1=1,1+1=0通过上面的定义,如果某一个可行状态加上转移向量得到的新向量还属于可行状态,则这两个可行状态对应的顶点之间就存在一条边。
农夫携物过河程序

题目内容:有一农夫要将自己的羊、蔬菜和狼等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的简单路径,即顶点序列中不重复出现的路径。
人工智能——状态图(狼羊菜)

⼈⼯智能——状态图(狼⽺菜)有⼀农夫带⼀只狼、⼀只⽺和⼀筐菜欲从河的左岸乘船到右岸,但受下列条件限制: (1)船太⼩,农夫每次只能带⼀样东西过河; (2)如果没有农夫看管,则狼要吃⽺,⽺要吃菜。
请⽤状态空间法设计⼀个过河⽅案,使得农夫、狼、⽺、菜都能不受损失地过河。
画出相应的状态空间图。
提⽰: (1)⽤四元组(农夫、狼、⽺、菜)表⽰状态,其中每个元素都可为0或1,⽤0表⽰在左岸,⽤1表⽰在右岸。
(2)把每次过河的⼀种安排作为⼀个算符,每次过河都必须有农夫,因为只有他可以划船。
解:状态⽤四元组表⽰为S(P,W,G,V),其中P为农民,W为狼,G为⽺,V为菜,B为船,B=0为船在左岸,1为船在右岸。
初始状态为S0=(0,0,0,0),⽬标状态为Sg=(1,1,1,1)。
安全规则: 1)不能将G与W单独留在对岸: not(W==G and P!=W); 2)不能单独将G与V留在对岸:not(G==V and G!=P)操作算符定义为:P(S)仅农夫过河:if (安全) then {P(S),得到⼀个新状态(1-P,W,G,V)};PG(S):农夫带⽺过河:if (安全) then {PG(S),得到⼀个新状态(1-P,W,1-G,V)};PW(S):农夫带狼过河:if (安全) then {PW(S),得到⼀个新状态(1-P,1-W,G,V)};PV(S):农夫带菜过河:if(安全)then {PV(S),得到⼀个新状态(1-P,W,G,1-V)}。
解: ①分析状态 因为以S(P,W,G,V)的形式且P,W,G,V只有0,1两种取值,所以有2*2*2*2种状态状态 (P,W,G,V)状态(P,W,G,V)状态(P,W,G,V)状态(P,W,G,V) S1(0,0,0,0)S5(0,1,0,0)S9(1,0,0,0)S13(1,1,0,0) S2(0,0,0,1)S6(0,1,0,1)S10(1,0,0,1)S14(1,1,0,1) S3(0,0,1,0)S7(0,1,1,0)S11(1,0,1,0)S15(1,1,1,0) S4(0,0,1,1)S8(0,1,1,1)S12(1,0,1,1)S16(1,1,1,1) 要求是从S1转换到S16。
算法的描述

%s'%(x,y,z))
*
做一做
给定年份判断是否是闰年
输入数字判断是否是水仙花数
*
谢谢观赏
感谢聆听
Make Presentation much more fun
@WPS官方微博 @kingsoftwps
第四步:最后把羊带过河。
用流程图来描述农夫过河的过程
流程图:
准备过河 农夫和羊过河,放下羊 农夫回来带白菜过河,放下白菜 农夫把羊带回来,放下羊,再带狼过河,放下狼
农夫回来,带羊过河 结束
用流程图描述算法
流程图(flow chart)是描述我们进行某一项活动所遵 循顺序的一种图示方法。
水费计算
开始
皮试
开始
皮下注射 y=2.85*第一 级用水量 +5.5*第二级 用水量 等待15分钟 否 是否过敏 可以 注射
输入用水量X X是否小于 等于20 是
y=2.85*第一级用 水量 否
是
不能注射
输出水费 结束
*
结束
用计算机语言描述算法
Python
Dim a As Integer, b As Integer, c As Integer for x in range(1.20):
算法思想初探
8年级信息组
2018-09-15
1 算法的描述
*
算法的描述
农夫、狼、 羊、菜
算法的描述(用自然语言描述)
我们使用了语言描述解决问题的过程,这种方法称为自 然语言描述算法。
第一步:农夫把羊先带过河,自己返回。 第二步:再把白菜带过河,同时把羊带回来。
第三步:把羊放下,然后把狼带过河,自己回来。
for y in range(1,33):
数据结构—农夫过河问题

题目:一个农夫带着一匹狼、一只羊、一颗白菜要过河,只有一条船而且农夫每次最多只能带一个动物或物品过河,并且当农夫不在的时候狼会吃羊,羊会吃白菜,列出所有安全将所有动物和物品带过河的方案。
要求:广度优先搜索农夫过河解,并输出结果源代码:#include <stdio.h>#include <stdlib.h>typedef int DataType;struct SeqQueue{int MAXNUM;int f, r;DataType *q;};typedef struct SeqQueue *PSeqQueue; // 顺序队列类型的指针类型PSeqQueue createEmptyQueue_seq(int m)//创建一个空队列{PSeqQueue queue = (PSeqQueue)malloc(sizeof(struct SeqQueue)); if (queue != NULL){queue->q = (DataType*)malloc(sizeof(DataType) *m);if (queue->q){queue->MAXNUM = m;queue->f = 0;queue->r = 0;return (queue);}elsefree(queue);}printf("Out of space!!\n"); // 存储分配失败return NULL;}int isEmptyQueue_seq(PSeqQueue queue)//判断队列是否为空{return (queue->f == queue->r);}void enQueue_seq(PSeqQueue queue, DataType x)//入队{if ((queue->r + 1) % queue->MAXNUM == queue->f)printf("Full queue.\n");else{queue->q[queue->r] = x;queue->r = (queue->r + 1) % queue->MAXNUM;}}void deQueue_seq(PSeqQueue queue)// 删除队列头部元素{if (queue->f == queue->r)printf("Empty Queue.\n");elsequeue->f = (queue->f + 1) % queue->MAXNUM;}DataType frontQueue_seq(PSeqQueue queue)//取队头元素{if (queue->f == queue->r)printf("Empty Queue.\n");elsereturn (queue->q[queue->f]);}int farmer(int location)//判断农夫的位置 1000表示在北岸{return (0 != (location &0x08));}int wolf(int location)//判断狼的位置 0100表示在北岸{return (0 != (location &0x04));}int cabbage(int location)//判断白菜的位置 0010表示在北岸{return (0 != (location &0x02));}int goat(int location)//判断羊的位置 0001表示在北岸{return (0 != (location &0x01));}int safe(int location)//安全状态的判断{if ((goat(location) == cabbage(location)) && (goat(location) != farmer(location))) //羊与白菜不安全return 0;if ((goat(location) == wolf(location)) && (goat(location) != farmer(location)))//羊与狼不安全return 0;return 1; // 其他状态是安全的}void bin_print(int num)//将十进制数转换成二进制数输出{char tmp[4];int i;for (i = 0; i < 4; ++i){tmp[i] = num & 0x01;num >>= 1;}for (i = 3; i >= 0; --i)putchar((tmp[i] == 0)?'0':'1');return;}int main(){int i, movers, location, newlocation;int a=0;int r[16];int route[16]; //用于记录已考虑的状态路径PSeqQueue moveTo; //用于记录可以安全到达的中间状态moveTo = createEmptyQueue_seq(20); //创建空队列enQueue_seq(moveTo, 0x00); //初始状态进队列for (i = 0; i < 16; i++)route[i] = -1; //准备数组route初值route[0] = 0;while (!isEmptyQueue_seq(moveTo) && (route[15] == - 1)){location = frontQueue_seq(moveTo); //取队头状态为当前状态deQueue_seq(moveTo);for (movers = 1; movers <= 8; movers <<= 1)//考虑各种物品移动 if ((0 != (location & 0x08)) == (0 != (location & movers)))//判断农夫与移动的物品是否在同一侧{newlocation = location ^ (0x08 | movers);//计算新状态,代表把船上的(0x08|movers)从一个岸移到另一个岸;(0x08|movers)代表船上有农夫和movers代表的东西if (safe(newlocation) && (route[newlocation] == -1)) //新状态安全且未处理{route[newlocation] = location; //记录新状态的前驱 enQueue_seq(moveTo, newlocation); //新状态入队}}}// 打印出路径if (route[15] != -1)//到达最终状态{printf("The reverse path is : \n");for (location = 15; location >= 0; location = route[location]) {r[a]=location;a++;if (location == 0) break;}for(i=a-1;i>=0;i--){printf("%d ",r[i]);bin_print(r[i]);//用1表示北岸,0表示南岸,用四位二进制数的顺序依次表示农夫、狼、白菜、羊的位置if(r[i]==0) printf("开始\n");//0000else if(r[i]==1) printf(" 农夫独自返回南岸\n"); //0001else if(r[i]==2) printf(" 农夫带着羊返回南岸\n");//0010else if(r[i]==3) printf(" 白菜与羊共同在北岸,不安全\n"); //0011else if(r[i]==4) printf(" 只有狼在北岸,农夫独自返回南岸\n"); //0100else if(r[i]==5) printf(" 狼与羊共同在北岸,不安全\n");//0101else if(r[i]==6) printf(" 农夫独自返回南岸\n");//0110else if(r[i]==7) printf(" 狼、白菜和羊共同在北岸,不安全\n");// 0111else if(r[i]==8) printf(" 农夫独自去北岸\n");//1000else if(r[i]==9) printf(" 农夫把羊带到北岸\n");//1001else if(r[i]==10) printf(" 农夫把白菜带到北岸\n");//1010else if(r[i]==11) printf(" 农夫把白菜带到北岸\n");//1011else if(r[i]==12) printf(" 农夫把狼带到北岸\n");//1100else if(r[i]==13) printf(" 只有白菜在南岸\n");//1101else if(r[i]==14) printf(" 农夫把狼带到北岸\n");//1110else if(r[i]==15) printf(" 农夫把羊带到北岸\n");//1111 putchar('\n');}printf("\n");}elseprintf("No solution.\n");}。
python狼羊蔬菜过河问题方法

python狼羊蔬菜过河问题方法
狼羊蔬菜过河问题是一个经典的逻辑推理问题,在解题过程中需要使用Python
编程语言来实现。
要解决这个问题,有几种常见的方法可以选择。
其中一种方法是使用深度优先搜索(DFS)算法来遍历所有可能的解决方案。
首先,我们可以定义一个函数来表示当前状态,即船的位置、狼、羊和蔬菜的位置。
然后,在每一步中,我们可以生成所有可能的下一步,并检查它们是否符合问题的规则,例如船上至多只能有两个物体,船上必须有人等等。
如果满足规则,我们可以继续递归调用该函数,直到找到解决方案或者无法找到合适的下一步。
另外一种方法是使用广度优先搜索(BFS)算法来遍历所有可能的解决方案。
在这种方法中,我们可以使用一个队列来存储当前状态,然后依次将每一个状态的可能下一步加入队列。
通过不断扩展当前状态的可能性,直到找到解决方案为止。
除了以上两种方法,还可以使用启发式搜索等其他算法来解决这个问题。
启发
式搜索是一种通过评估当前状态与目标状态之间的差异来选择下一步的算法。
可以使用一些启发式函数来估计当前状态与目标状态之间的差异,然后根据这个评估结果来选择下一步。
综上所述,解决狼羊蔬菜过河问题可以使用深度优先搜索、广度优先搜索、启
发式搜索等多种方法。
通过合理地利用这些算法,我们可以找到有效的解决方案。
值得注意的是,对于更复杂的问题,可能需要更高级的算法和技巧来解决。
狼羊白菜实验报告

南京邮电大学通达学院程序设计(上机)报告题目:R004M,P005H专业网络工程学生姓名班级学号指导教师日期评分细则评分项优秀良好中等及格不及格遵守机房规章制度上机表现学习态度基础知识水平程序设计能力课题功能实现情况算法设计合理性用户界面友好性报告书写认真程度报告内容完整性文字表达清楚程度问题回答准确性评分等级教师签名:年月日备注注:评分等级分为五种:优秀、良好、中等、及格、不及格狼羊白菜过河程序实验报告一.问题描述一个人带着一只羊,一条狼和一颗白菜想过河,假设他每次只能带一只羊,或者一条狼,或者一颗白菜过河,并限定人不在场时,狼和羊,或羊和白菜不能单独在一起,试编写程序求出他带一只羊,一条狼和一颗白菜过河的办法。
二.结构图三、结构设计1、 狼和羊、羊和白菜不能单独在一起,涉及对象较多,而且运算步骤方法较为复杂,要用程序语言实现,需要将具体实例数字化。
针对实现整个过程需要多步,不同步骤中各个事物所处位置不同的情况,可定义一个二维数组或者结构体来实现对四个对象狼、羊、白菜和一个人的表示。
对于岸的两侧可以用0或者1来表示,以实现在程序设计中的简便性。
2、对狼羊白菜的过河步骤,没有顺序的约束,因此需要给各个事物依次进行编号,然后依次尝试,若成功,进行下一步,使用循环或者递归算法进行程序3、程序使用递归算法,为了方便将各个实例数字化。
定义二维数组int a[M][4]存储每一步中各个对象所处的位置,用0-3分别表示二维数组的一维下标。
具体对应为:wolf-0 goat-1 cabbage-2 people-3将本岸和对岸数字化,其对应为:本(东)岸-0 对(西)岸-1具体对应实例比如在第3步之后狼在本岸,羊在对岸,白菜在本岸,农夫在对岸,则其存储结果为:a[3][0] a[3][1] a[3][2] a[3][3]过河农夫选择相斥共存程序运行输出结果0 1 0 1最初存储状态为:a[0][0] a[0][1] a[0][2] a[0][3]0 0 0 0成功渡河之后,二维数组存储应为:a[istep][0] a[istep][1] a[istep][2] a[istep][3]1 1 1 1因此a[iStep][0] + a[iStep][1] + a[iStep][2] + a[iStep][3] == 4。
实验6:农夫、狼、羊和菜问题

实验6 :农夫、狼、羊和菜问题、实验目的:1. 会定义图的抽象数据类型;2. 熟悉图的基本结构,掌握程序中的用户头文件、实现文件和主文件之间的相互关系及各自的作用;3. 熟悉对图的一些基本操作和具体的函数定义;4. 掌握在实际问题中运用所学知识解决实际问题的方法和步骤。
二、实验内容描述:有一农夫带着一条狼、一只羊和一筐菜,想从河的左岸乘船到右岸。
但由于船太小,农夫每次只能带一样东西过河,而且,如果没有农夫看管,则狼会吃羊,羊会吃菜。
问农夫怎样过河才能把每样东西安全地送过河。
三、实验要求:1. 将上述问题用图表示出来;2. 选择图的一种存储结构,编写一个自动生成该图的算法;3. 在上述基础上编写求解该问题的算法程序,并用此程序上机运行、调试,4. 屏幕显示结果,能结合程序进行分析。
四、问题分析:该问题从表面上看,并不是一个图的问题,但可以把它用图表示出来,从而转换为一个图的问题。
在这个问题的解决过程中,农夫需要多次架船往返于两岸之间,每次可以带一样东西或者自己单独过河,每一次过河都会使农夫、狼、羊和菜所处的位置发生变化。
如果用一个四元组( Farmer,Wolf,Sheep,Veget )表示当前农夫、狼、羊和菜所处的位置,其中每个元素可以是0 或1,0 表示在左岸,1表示在右岸。
这样,对这四个元素的不同取值可以构成16 种不同的状态,初始时的状态则为( 0,0,0,0),最终要达到的目标为( 1,1,1,1)。
状态之间的转换可以有下面四种情况:(1)农夫不带任何东西过河,可表示为:(Farmer,Wolf,Sheep,Veget)(!Farmer,Wolf,Sheep,Veget) ( 2)当农夫和狼在相同位置时,表示农夫带狼过河,即当Farmer=Wolf 时:(Farmer,Wolf,Sheep,Veget) (!Farmer,!Wolf,Sheep,Veget)(3)当农夫和羊在相同位置时,表示农夫带羊过河,即当Farmer=SheeP时:(Farmer,Wolf,Sheep,Veget) (!Farmer,Wolf,!Sheep,Veget)(4)当农夫和菜在相同位置时,表示农夫带菜过河,即当Farmer=Veget时:(Farmer,Wolf,Sheep,Veget) (!Farmer,Wolf,Sheep,!Veget)在这16种状态中,有些状态是不安全的,是不允许出现的,如( 1,1, 0, 0)表示农夫和狼在右岸,而羊和菜在左岸,这样羊会吃掉菜。
人狼羊菜过河问题的解法及代码

⼈狼⽺菜过河问题的解法及代码⼈狼⽺菜问题是计算机领域中的经典问题。
之所以经典,⼀⽅⾯这是编译原理等课程中的⼀个建模及编码问题,另⼀⽅⾯也经常被作为智⼒题⽤在⾯试中。
本⽂讨论的是怎么建模、编码的问题。
问题描述:⼀个农夫有⼀条船,和狼、⽺、菜,农夫要把这3样东西运到河到另⼀边,农夫每次最多只能通过这个船运⼀样东西,要防⽌狼吃⽺、⽺吃⽩菜(即不能在没有农夫在的情况下同时在同⼀岸边),该怎么过?该问题的解决分为2个阶段,第⼀阶段是对状态建模,第⼆阶段是⽤⼴度遍历来找到问题的解。
其中⼴度遍历阶段和“量⽔问题”的⼴度遍历解法类似。
问题抽象:建⽴⼀个struct型的state,其中包括4个bool型的变量a1 a2 a3 a4分别对应⼈、狼、⽺、菜的状态,值为true代表在起始的河岸边,false代表在对岸,起始时4个分量都为true。
农夫每过⼀次河⽣成⼀个新的state。
根据题⽬可知,农夫过⼀次河a1取反,且a2 a3 a4值与a1相同的分量也可以分别取反分别⽣成⼀个新的state代表被农夫运到河的对岸的各种选择。
只有a1取反⽽a2 a3 a4都没取反⽣成的新状态代表农夫⾃⼰过河没有带东西。
每次⽣成⼀个新状态后,⾸先要检查是否达到了终⽌状态(a1 a2 a3 a4都为false),其次要检查是否是合法状态(要同时考虑⼀个state对应的河两岸是否有狼吃⽺、⽺吃⽩菜的情况出现),如果状态合法、没到终⽌状态且没有在⼴度遍历队列中出现过,则将状态插⼊⼴度遍历队列,否则将该状态丢弃。
在此过程中我们没有考虑正在渡河的情况,因为每次过河船上总是有⼈,不会出现冲突,视其为不稳定状态直接忽略。
代码如下:#include<iostream>using namespace std;#define MAX 500struct state{bool a1,a2,a3,a4;int parentId;//⽤于回溯输出解决步骤state(){a1 = a2 = a3 = a4 = true;//true表⽰在A地(起始岸边)parentId=-1;}};bool equal(state& astate,state& bstate){if(astate.a1==bstate.a1&&astate.a2==bstate.a2&&astate.a3==bstate.a3&&astate.a4==bstate.a4){return true;}return false;}void assign(state& astate,state& bstate){astate.a1=bstate.a1;astate.a2=bstate.a2;astate.a3=bstate.a3;astate.a4=bstate.a4;astate.parentId = bstate.parentId;}state currentState;state sQueue[MAX];int startPos = 0;int endPos = 1;bool isInQueue(state& newState){for(int i=0;i<endPos;i++){if(equal(newState,sQueue[i])){return true;}}return false;}bool isValidState(state& newState){//总共可能有16种状态。
农夫过河问题状态图及程序

农夫过河问题状态图及程序一、问题需求分析一个农夫带着一只狼、一只羊和一棵白菜,身处河的南岸。
他要把这些东西全部运到北岸。
问题是他面前只有一条小船,船小到只能容下他和一件物品,另外只有农夫能撑船。
另外,因为狼能吃羊,而羊爱吃白菜,所以农夫不能留下羊和白菜或者狼和羊单独在河的一边,自己离开。
请问农夫该采取什么方案才能将所有的东西运过河呢?二、算法选择求解这个问题的最简单的方法是一步一步进行试探,每一步都搜索所有可能的选择,对前一步合适的选择再考虑下一步的各种方案。
用计算机实现上述求解的搜索过程可以采用两种不同的策略:一种是广度优先(breadth_first) 搜索,另一种是深度优先(depth_first) 。
广度优先:u 广度优先的含义就是在搜索过程中总是首先搜索下面一步的所有可能状态,然后再进一步考虑更后面的各种情况。
u 要实现广度优先搜索,一般都采用队列作为辅助结构。
把下一步所有可能达到的状态都列举出来,放在这个队列中,然后顺序取出来分别进行处理,处理过程中把再下一步的状态放在队列里……。
u 由于队列的操作遵循先进先出的原则,在这个处理过程中,只有在前一步的所有情况都处理完后,才能开始后面一步各情况的处理。
三、算法的精化要模拟农夫过河问题,首先需要选择一个对问题中每个角色的位置进行描述的方法。
一个很方便的办法是用四位二进制数顺序分别表示农夫、狼、白菜和羊的位置。
例如用0表示农夫或者某东西在河的南岸,1表示在河的北岸。
因此整数5(其二进制表示为0101) 表示农夫和白菜在河的南岸,而狼和羊在北岸。
四、算法的实现完成了上面的准备工作,现在的问题变成:从初始状态二进制0000(全部在河的南岸) 出发,寻找一种全部由安全状态构成的状态序列,它以二进制1111(全部到达河的北岸) 为最终目标,并且在序列中的每一个状态都可以从前一状态通过农夫(可以带一样东西)划船过河的动作到达。
为避免不必要的瞎费功夫,要求在序列中不应该出现重复的状态。
1.1使用计算机解决问题的一般过程

转化
For i = 0 To 20
For j = 0 To 33
k = 100 - i - j
If i * 5 + j * 3 + k / 3 = 100 Then Picture1.Print “ 公鸡为” & i & “只,母鸡 为” & j & “只,小鸡为" & k & "只"
1 观察分析问题
狼羊菜过河游戏规则
2 寻找解题的方法
找到正确的过河方案
3 解决问题
按照找到的方案过河
4 验证结果
检验结果的准确性
百钱买来百只鸡,公母小鸡数不齐; 母一钱三公钱五,三雏钱一价格低。 公鸡母鸡各多少,还有几只是小鸡?
1.设公鸡母鸡小鸡分别为i,j,k 2.由已知的条件可得到方程5i+3j+k/3=100
辽宁省大石桥市高级中学 李翠娥
狼羊菜过河游戏
狼羊菜过河,一人要将一狼、一 羊、一棵白菜这些东西都运送到河对 岸。渡船太小,一次只能带一样。因 为狼要吃羊,羊会吃白菜,所以狼和 羊,羊和白菜不能在无人监视的情况 下相处。
农夫带羊过河 把羊带回来 带羊过河
农夫回来
带狼(菜)过河
带菜(狼)过河
农夫回来
Next j, i
分析问题
确 定 要 做 什 么
核心
设计算法
如 何 做
编写程序
翻 译 , 将 算 法 编 写 成 程 序
调试运行
运 行 程 序 , 验 证 结 果
解决问题的方式 人工解决
(状态机)狼羊菜过河的程序

过河问题大家都知道,不多说了.解决这个问题的经典方法就是使用有限状态机. 根据人,狼,羊,菜,在不同河岸,可以抽象出N种不同的状态.某些状态之间可以转换. 这些转换就是运算了. 我们的目的就是找到一组这样的运算,可以从初始状态转换到终止状态. 其间的状态必需都是合法的. C++代码如下:/*-------------------------------------农夫,狼,羊,菜,过河--------------------------------------*/#include <list>#include <iostream>enum PLACE{NO, // 没有过河的YES, // 已经过河了};// 状态typedef struct{PLACE man; // 人的状态PLACE wolf; // 狼的状态PLACE sheep; // 羊有状态PLACE menu; // 菜的状态} STATUS;const STATUS c_start = {NO,NO,NO,NO}; // 起始状态const STATUS c_end = {YES,YES,YES,YES}; // 终止状态// 结点(保存转换路径)typedef struct TURN{STATUS status;TURN* p;}TURN;typedef std::list<TURN> LIST_TURN;typedef std::list<TURN*> LIST_NODE;// 判断两个状态是否一致bool operator == (const STATUS& sa, const STATUS& sb){return sa.man == sb.man && sa.wolf == sb.wolf &&sa.sheep == sb.sheep && sa.menu == sb.menu;}// 查找状态是否已经存在bool Find(LIST_TURN& ls, const STATUS& s){LIST_TURN::iterator it = ls.begin();for(;it!=ls.end(); it++){if((*it).status==s)return true;}return false;}// 状态转换运算enum OPERATOR{MAN_GO, // 人过河MAN_GO_WI TH_WOLF, // 人带狼过河MAN_GO_WI TH_SHEEP, // 人带羊过河MAN_GO_WI TH_MENU, // 人带菜过河MAN_BACK, // 人回来MAN_BACK_WI TH_WOLF, // 人带狼回来MAN_BACK_WI TH_SHEEP, // 人带羊回来MAN_BACK_WI TH_MENU, // 人带菜回来OP_FIRST = MAN_GO,OP_LAST = MAN_BACK_WITH_MENU,};// 状态转换bool StatusTurn(const STATUS& src, OPERATOR op, STATUS& desc) {switch(op){case MAN_GO: // 人过河if(src.man == NO) {desc = src;desc.man = YES;return true;}break;case MAN_GO_WI TH_WOLF: // 人带狼过河if(src.man == NO && src.wolf == NO){desc = src;desc.man = YES;desc.wolf = YES;return true;}break;case MAN_GO_WI TH_SHEEP: // 人带羊过河if(src.man == NO && src.sheep == NO) {desc = src;desc.man = YES;desc.sheep = YES;return true;}break;case MAN_GO_WI TH_MENU: // 人带菜过河if(src.man == NO && src.menu == NO) {desc = src;desc.man = YES;desc.menu = YES;return true;}break;case MAN_BACK: // 人回来if(src.man == YES) {desc = src;desc.man = NO;return true;}break;case MAN_BACK_WI TH_WOLF: // 人带狼回来if(src.man == YES && src.wolf == YES) { desc = src;desc.man = NO;desc.wolf = NO;return true;}break;case MAN_BACK_WI TH_SHEEP: // 人带羊回来if(src.man == YES && src.sheep == YES) {desc = src;desc.man = NO;desc.sheep = NO;return true;}break;case MAN_BACK_WI TH_MENU: // 人带菜回来if(src.man == YES && src.menu == YES) {desc = src;desc.man = NO;desc.menu = NO;return true;}break;}return false;}// 状态检测(检测合法的状态)bool StatusTest(const STATUS& s){// 人不在的时候,狼会吃羊,羊会吃菜if(s.man != NO){if(s.wolf == NO && s.sheep == NO || s.sheep == NO && s.menu == NO)return false;}if(s.man != YES){if(s.wolf == YES && s.sheep == YES || s.sheep == YES && s.menu == YES)return false;}return true;}int main(){LIST_TURN history; // 已经搜索过的状态LIST_NODE active; // 需要搜索的状态// 生成起始结点TURN turn;turn.status = c_start;turn.p = 0;history.push_back(turn);active.push_back(&history.back());// 初始化bool bFind = false;TURN* pend = 0;// 状态转换图搜索(广度优先,求转换次数最少的路径)while(!active.empty()){// 待搜索的当前结点TURN* pact = active.front();active.pop_front();// 如果等于终止状态,则搜索成功if(pact->status == c_end){bFind = true;pend = pact;break;}// 计算当前状态的所有可能的下一个状态for(OPERATOR op = OP_FIRST; op <= OP_LAST; op=(OPERATOR)(op+1)) {TURN next;// 下一个状态满足:// (1) 有一个转换运算从当前状态转换到此状态// (2) 此状态是有效的状态// (3) 此状态是一个新状态.已经搜索过的状态不用再搜索if(StatusTurn(pact->status, op, next.status) &&StatusTest(next.status) && !Find(history, next.status)){// 为搜索图添加下一个结点next.p = pact;history.push_back(next);active.push_back(&history.back());}}// 如果找到if(bFind){// 计算路径active.clear();TURN* p = pend;while(p){active.push_front(p);p = p->p;}// show nodefor(LIST_NODE::iterator i t= active.begin(); it != active.end(); i t++){if((*it)->status.man == NO) std::cout << "[人]"; else std::cout << "[..]"; if((*it)->status.wolf == NO) std::cout << "[狼]"; else std::cout << "[..]"; if((*it)->status.sheep == NO) std::cout << "[羊]"; else std::cout << "[..]"; if((*it)->status.menu == NO) std::cout << "[菜]"; else std::cout << "[..]"; std::cout << " <=====> ";if((*it)->status.man == YES) std::cout << "[人]"; else std::cout << "[..]"; if((*it)->status.wolf == YES) std::cout << "[狼]"; else std::cout << "[..]"; if((*it)->status.sheep == YES) std::cout << "[羊]"; else std::cout << "[..]"; if((*it)->status.menu == YES) std::cout << "[菜]"; else std::cout << "[..]";std::cout << std::endl;}}else{std::cout<<"Not Found!" << std::endl;}return 0;}。
狼羊过河问题

狼、羊、菜过河问题1.模型建立用0-1将人、狼、羊、菜河这边的所有状态表示出来(其中状态1代表在河这边,状态0代表在河对岸),共有16种状态。
由题设条件知,状态(0,1,1,0),(0,0,1,1)(0,1,1,1,)是不允许的,从而对应状态(1,0,0,1)(1,1,0,0)(1,0,0,0,)也是不允许的。
最后得到10种状态。
将它们分别标号如下:1(1 1 1 1)2(1 0 1 1)3(0 0 0 1)4(1 1 0 1)5(1 1 1 0)6(1 0 1 0)7(0 1 0 1)8(0 1 0 0)9(0 0 1 0)10(0 0 0 0)然后将各状态能够相互转移的状态用1表示,不能相互转移的状态用无穷大inf表示,得到关于这10种状态的一个10*10的邻接矩阵。
利用Floyd算法,在matlab上运行,即可找出该过河问题的最佳答案。
所得的邻接矩阵如下:[inf inf inf inf inf inf 1 inf inf infinf inf 1 inf inf inf inf inf 1 infinf 1 inf 1 inf inf inf inf inf infinf inf 1 inf inf inf 1 1 inf infinf inf inf inf inf inf inf 1 1 infinf inf inf inf inf inf inf inf 1 11 inf inf 1 inf inf inf inf inf infinf inf inf 1 1 inf inf inf inf infinf 1 inf inf 1 1 inf inf inf infinf inf inf inf inf 1 inf inf inf inf ]利用Floyd算法:function [D,path]=floyd(a)n=size(a,1);D=a;path=zeros(n,n);for i=1:nfor j=1:nif D(i,j)~=infpath(i,j)=j;endendendfor k=1:nfor i=1:nfor j=1:nif D(i,k)+D(k,j)<D(i,j)D(i,j)=D(i,k)+D(k,j);path(i,j)=path(i,k);endendendendfunction [L,R]=router(D,path,1,10)L=zeros(0,0);R=s;while 1if s==tL=fliplr(L);L=[0,L];returnendL=[L,D(s,t)];R=[R,path(s,t)];s=path(s,t);End输入a=[inf inf inf inf inf inf 1 inf inf infinf inf 1 inf inf inf inf inf 1 infinf 1 inf 1 inf inf inf inf inf infinf inf 1 inf inf inf 1 1 inf infinf inf inf inf inf inf inf 1 1 infinf inf inf inf inf inf inf inf 1 11 inf inf 1 inf inf inf inf inf infinf inf inf 1 1 inf inf inf inf infinf 1 inf inf 1 1 inf inf inf infinf inf inf inf inf 1 inf inf inf inf ]得到:D =2 43 24 6 1 35 74 2 1 2 2 2 3 3 1 33 1 2 1 3 3 2 2 2 42 2 1 2 2 4 1 13 54 2 3 2 2 2 3 1 1 36 2 3 4 2 2 5 3 1 11 32 13 5 2 24 63 3 2 1 1 3 2 2 2 45 1 2 3 1 1 4 2 2 27 3 4 5 3 1 6 4 2 2path =7 7 7 7 7 7 7 7 7 73 3 3 3 9 9 3 3 9 94 2 2 4 4 2 4 4 2 27 3 3 3 8 3 7 8 3 38 9 8 8 8 9 8 8 9 99 9 9 9 9 9 9 9 9 101 4 4 4 4 4 1 4 4 44 4 4 45 5 4 4 5 52 2 2 2 5 6 2 5 2 66 6 6 6 6 6 6 6 6 6L =0 1 2 3 4 5 6 7R =1 7 4 32 9 6 10可得到过河的状态转移为:1---7---4---3---2---9---6---10即人将羊送到河对岸,回来再将狼送到河对岸,在对岸将羊拉回来,再将菜送到河对岸,回来时再和羊一起到河对岸,人狼羊菜全部过河,问题得到解决。
农夫过河问题算法设计与实现

农夫过河问题算法设计与实现咱来唠唠农夫过河这个有趣的问题。
一、问题描述农夫要带着一只狼、一只羊和一棵白菜过河。
但是呢,船很小,每次农夫只能带一样东西过河。
而且啊,如果农夫不在,狼会吃羊,羊会吃白菜,这可就麻烦大了。
二、算法设计思路1. 初始状态- 河这边有农夫、狼、羊和白菜,河对岸啥都没有。
2. 第一步很关键- 农夫肯定不能先带狼或者白菜,为啥呢?因为如果先带狼过去,把羊和白菜留在这边,羊就会吃白菜;要是先带白菜过去,狼就会吃羊。
所以农夫得先带羊过河。
- 然后农夫自己返回。
这时候河这边有狼和白菜,河对岸有羊。
3. 第二步- 农夫再带狼或者白菜过河。
假设农夫带狼过河吧。
- 但是农夫不能把羊单独留在对岸啊,所以农夫得把羊再带回来。
这时候河这边有羊和白菜,河对岸有狼。
4. 第三步- 农夫把羊放下,带白菜过河。
- 然后农夫自己返回。
这时候河这边有羊,河对岸有狼和白菜。
5. 最后一步- 农夫再带羊过河,这样就都安全地到对岸啦。
三、算法实现(用简单的文字描述过程)1. 开始:- 农夫在起始岸,物品(狼、羊、白菜)也在起始岸,对岸为空。
2. 第一次过河:- 农夫带羊过河,此时起始岸有狼和白菜,对岸有羊和农夫。
- 农夫独自返回起始岸,此时起始岸有农夫、狼、白菜,对岸有羊。
3. 第二次过河:- 农夫带狼过河,此时起始岸有白菜,对岸有狼、羊和农夫。
- 农夫带羊返回起始岸,此时起始岸有农夫、羊、白菜,对岸有狼。
4. 第三次过河:- 农夫带白菜过河,此时起始岸有羊,对岸有狼、白菜和农夫。
- 农夫独自返回起始岸,此时起始岸有农夫、羊,对岸有狼、白菜。
5. 第四次过河:- 农夫带羊过河,此时起始岸为空,对岸有农夫、狼、羊、白菜,大功告成!你看,这样一步一步的,就像走迷宫一样,按照规则走,就能让农夫带着他的东西安全过河啦。
1.2.1算法

例1:给出求1+2+3+4+5的一个算法。 算法1:按照逐一相加的程序进行.
第一步 计算1+2,得到3; 第二步 将第一步中的运算结果3与3相加,得到6; 第三步 将第二步中的运算结果6与4相加,得到10; 第四步 将第三步中的运算结果10与5相加,得到15.
有一个或多个输出
思考:能用算法3求1+3+5+…+99吗?
请你写出解下面二元一次方程组的详细过程.
x 2y 1 ① 2x y 1 ②
解: 第一步, ①×1+②×2得 5x=1; ③
第二步, 解③得x 1 ; 5
第三步, ②×1-① ×2得 5y=3;
④
第四步, 第五步,
解④得y 3 ; 5
软件
软核件心
算法
算法的概念
算法的概念
【过河问题】:有一个牧羊人带着一头羊,一只狼和一颗大白菜准备过河,他 找到一只很小的船,每次只能带一样东西过去,可是如果让狼与羊单独在一 起,狼会吃羊,让羊与白菜单独在一起,羊会吃白菜,牧羊人应如何过河?
算法的概念
步骤1:人和羊过河,人返回,留下羊;
算法的概念
算法的特征 算法确的定有性穷性 有效性
有零个或多个输入 有一个或多个输出
有穷性:一个算法的步骤序列是有限的,它应在 有限步操作之后停止,而不能是无限地执行下去。
确定性:算法中的每一步应该是确定的并且能有 效地执行且得到确定的结果,而不应当是模棱两 可的。
如:1、让机器人手举过头顶 2、10÷正整数
有效性:算法中的每一个步骤都应当能有效的执 行,并得到确定的结果。
如果有一条河,你只能过一次,而且没有船或桥,你如何带着一只狼、一只羊和一颗白菜过河?

如果有一条河,你只能过一次,而且没有船或桥,你如何带着一只狼、一只羊和一颗白菜过河?
这个问题是一个经典的逻辑谜题。
在解答之前,我们需要考虑到一些限制条件:
1. 你只能带一样东西过河,每次只能带一种东西。
2. 如果没有你在场,狼会吃掉羊,羊会吃掉白菜。
为了解决这个问题,我们可以按照以下步骤进行:
1. 首先,你带着羊过河,将羊放在对岸,然后返回原岸。
2. 接下来,你带着狼过河,但是你要将狼带回原岸,因为如果你离开狼和白菜
在一起,狼会吃掉白菜。
3. 然后,你将狼放回原岸,然后带着白菜过河,将白菜放在对岸。
4. 最后,你返回原岸,带着羊过河。
通过按照以上步骤,你可以成功地带着狼、羊和白菜过河,而不会出现任何问题。
这是因为在每一次过河的过程中,你都确保了没有让狼和羊、羊和白菜在
一起,避免了可能发生的危险情况。
希望这个解答能够帮助你锻炼思维逻辑!。
程序设计简介

举1、例把:羊编特带写对点计岸算:半径接为近圆的人周长们和日面积常的程使序用。 的自然语言(主要是英语)容易理解、记忆
特点:接近人们日常使用的自然语言(主要是英语)容易理解、记忆和使用,可在不同计算机上通用,对使用的符号、词汇、语法和
两种方式的区别在于翻译的时间,编译是在程序运行之前,需要一个专 门的过程,将程序编译成为机器语言的文件,比如EXE文件,以后要运行的 话就不用再重新编译了,直接使用之前的编译结果就行了,因为只翻译一次, 运行时不需要再翻译,所以编译型语言的程序执行效率高。
解释性语言则不同,解释性语言不需要编译,其程序在运行时才翻译, 每个语句都是执行时才翻译。这样解释性语言每执行一次就要翻译一次,其 执行效率则相对较低。
自然语言是指人们日 常生活中使用的语言,如汉 语、英语、法语等。
二、体验计算机程序
Basic语言 Let a = 3 Let h = 2.5 Let s = a * h / 2 Print s
自然语言 将3存入a中 将2.5存入h中 计算出三角形的面积,再存入s中 显示s中的值
实践学习: 输入与运行“求三角形面积”程序 1、打开桌面文件夹中的三角形面积.vbp文件进入Basic软件并输 入程序 2、按F5健运行程序,屏幕上即出现显示三角形面积的窗体
7计、算把的羊值带例对岸:51+53
Let a=51
Let b=53
Let s=a+b
Print s
问题:猎人带着一只狼,一头羊和一些白菜过河,但渡船太小,一次只能带一样。
常用高级语言种类:适用于数值计算的FORTRAN语言 易学好用的BASIC语言 适用于编写系统软件的C语言等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
过河问题大家都知道,不多说了.解决这个问题的经典方法就是使用有限状态机. 根据人,狼,羊,菜,在不同河岸,可以抽象出N种不同的状态.某些状态之间可以转换. 这些转换就是运算了. 我们的目的就是找到一组这样的运算,可以从初始状态转换到终止状态. 其间的状态必需都是合法的. C++代码如下:/*-------------------------------------农夫,狼,羊,菜,过河--------------------------------------*/#include <list>#include <iostream>enum PLACE{NO, // 没有过河的YES, // 已经过河了};// 状态typedef struct{PLACE man; // 人的状态PLACE wolf; // 狼的状态PLACE sheep; // 羊有状态PLACE menu; // 菜的状态} STATUS;const STATUS c_start = {NO,NO,NO,NO}; // 起始状态const STATUS c_end = {YES,YES,YES,YES}; // 终止状态// 结点(保存转换路径)typedef struct TURN{STATUS status;TURN* p;}TURN;typedef std::list<TURN> LIST_TURN;typedef std::list<TURN*> LIST_NODE;// 判断两个状态是否一致bool operator == (const STATUS& sa, const STATUS& sb){return sa.man == sb.man && sa.wolf == sb.wolf &&sa.sheep == sb.sheep && sa.menu == sb.menu;}// 查找状态是否已经存在bool Find(LIST_TURN& ls, const STATUS& s){LIST_TURN::iterator it = ls.begin();for(;it!=ls.end(); it++){if((*it).status==s)return true;}return false;}// 状态转换运算enum OPERATOR{MAN_GO, // 人过河MAN_GO_WI TH_WOLF, // 人带狼过河MAN_GO_WI TH_SHEEP, // 人带羊过河MAN_GO_WI TH_MENU, // 人带菜过河MAN_BACK, // 人回来MAN_BACK_WI TH_WOLF, // 人带狼回来MAN_BACK_WI TH_SHEEP, // 人带羊回来MAN_BACK_WI TH_MENU, // 人带菜回来OP_FIRST = MAN_GO,OP_LAST = MAN_BACK_WITH_MENU,};// 状态转换bool StatusTurn(const STATUS& src, OPERATOR op, STATUS& desc) {switch(op){case MAN_GO: // 人过河if(src.man == NO) {desc = src;desc.man = YES;return true;}break;case MAN_GO_WI TH_WOLF: // 人带狼过河if(src.man == NO && src.wolf == NO){desc = src;desc.man = YES;desc.wolf = YES;return true;}break;case MAN_GO_WI TH_SHEEP: // 人带羊过河if(src.man == NO && src.sheep == NO) {desc = src;desc.man = YES;desc.sheep = YES;return true;}break;case MAN_GO_WI TH_MENU: // 人带菜过河if(src.man == NO && src.menu == NO) {desc = src;desc.man = YES;desc.menu = YES;return true;}break;case MAN_BACK: // 人回来if(src.man == YES) {desc = src;desc.man = NO;return true;}break;case MAN_BACK_WI TH_WOLF: // 人带狼回来if(src.man == YES && src.wolf == YES) { desc = src;desc.man = NO;desc.wolf = NO;return true;}break;case MAN_BACK_WI TH_SHEEP: // 人带羊回来if(src.man == YES && src.sheep == YES) {desc = src;desc.man = NO;desc.sheep = NO;return true;}break;case MAN_BACK_WI TH_MENU: // 人带菜回来if(src.man == YES && src.menu == YES) {desc = src;desc.man = NO;desc.menu = NO;return true;}break;}return false;}// 状态检测(检测合法的状态)bool StatusTest(const STATUS& s){// 人不在的时候,狼会吃羊,羊会吃菜if(s.man != NO){if(s.wolf == NO && s.sheep == NO || s.sheep == NO && s.menu == NO)return false;}if(s.man != YES){if(s.wolf == YES && s.sheep == YES || s.sheep == YES && s.menu == YES)return false;}return true;}int main(){LIST_TURN history; // 已经搜索过的状态LIST_NODE active; // 需要搜索的状态// 生成起始结点TURN turn;turn.status = c_start;turn.p = 0;history.push_back(turn);active.push_back(&history.back());// 初始化bool bFind = false;TURN* pend = 0;// 状态转换图搜索(广度优先,求转换次数最少的路径)while(!active.empty()){// 待搜索的当前结点TURN* pact = active.front();active.pop_front();// 如果等于终止状态,则搜索成功if(pact->status == c_end){bFind = true;pend = pact;break;}// 计算当前状态的所有可能的下一个状态for(OPERATOR op = OP_FIRST; op <= OP_LAST; op=(OPERATOR)(op+1)) {TURN next;// 下一个状态满足:// (1) 有一个转换运算从当前状态转换到此状态// (2) 此状态是有效的状态// (3) 此状态是一个新状态.已经搜索过的状态不用再搜索if(StatusTurn(pact->status, op, next.status) &&StatusTest(next.status) && !Find(history, next.status)){// 为搜索图添加下一个结点next.p = pact;history.push_back(next);active.push_back(&history.back());}}// 如果找到if(bFind){// 计算路径active.clear();TURN* p = pend;while(p){active.push_front(p);p = p->p;}// show nodefor(LIST_NODE::iterator i t= active.begin(); it != active.end(); i t++){if((*it)->status.man == NO) std::cout << "[人]"; else std::cout << "[..]"; if((*it)->status.wolf == NO) std::cout << "[狼]"; else std::cout << "[..]"; if((*it)->status.sheep == NO) std::cout << "[羊]"; else std::cout << "[..]"; if((*it)->status.menu == NO) std::cout << "[菜]"; else std::cout << "[..]"; std::cout << " <=====> ";if((*it)->status.man == YES) std::cout << "[人]"; else std::cout << "[..]"; if((*it)->status.wolf == YES) std::cout << "[狼]"; else std::cout << "[..]"; if((*it)->status.sheep == YES) std::cout << "[羊]"; else std::cout << "[..]"; if((*it)->status.menu == YES) std::cout << "[菜]"; else std::cout << "[..]";std::cout << std::endl;}}else{std::cout<<"Not Found!" << std::endl;}return 0;}。