猴子摘香蕉问题
一、问题描述
利用一阶谓词逻辑求解猴子摘香蕉问题:房内有一个猴子,一个箱子,天花板上挂了一串香蕉,其位置如图1所示,猴子为了拿到香蕉,它必须把箱子搬到香蕉下面,然后再爬到箱子上。请定义必要的谓词,列出问题的初始化状态(即下图所示状态),目标状态(猴子拿到了香蕉,站在箱子上,箱子位于位置b)。
二、迟来的的代码
#include <stdio.h> #define Yes 1 // monkey on the box #define No 0 // monkey doesn't on the box #define maxStep 150 // monkey can do the max steps // define the problem states struct struct States { char box; // box location char monkey; // monkey location char banana; // banana location short Onbox; // monkey on the box }states[maxStep]; static int n = 0; // count step // initialize problem states void init() { printf("please input the banana location: "); scanf("%c", &states[0].banana); printf("please input the monkey location: "); scanf("n%c", &states[0].monkey); printf("please input the box location: "); scanf("n%c", &states[0].box); // if the monkey and box aren't in the same place, // then predicts monkey doesn't on the box if(states[0].monkey != states[0].box) { states[0].Onbox = No; } else { printf("Is the monkey on the box now? (1/0)"); scanf("n%hd", &states[0].Onbox); } } // monkey reach the banana void reach(int i) { printf("monkey reach the bananan"); n++; } // monkey go to location void monkeyGoto(int i, char location) { printf("monkey go to %cn", location); states[i+1] = states[i]; states[i+1].monkey = location; // change monkey location n++; } // monkey climb on the box void climbOnbox(int i) { printf("monkey climb on the boxn"); states[i+1] = states[i]; states[i+1].Onbox = Yes; n++; } // monkey climb down the box void climbDownbox(int i) { printf("monkey climb down the boxn"); states[i+1] = states[i]; states[i+1].Onbox = No; n++; } // monkey move the box to dest void moveBox(int i, char dest) { printf("monkey move the box to %cn", dest); states[i+1] = states[i]; states[i+1].monkey = dest; // change monkey location states[i+1].box = dest; // change box location n++; } // monkey do next Step int nextStep(int i) { if (i >= maxStep) { printf("Steps are too more, monkey can't go again!/n"); return No; } // if the banana and box are in the same place if(states[i].banana == states[i].box) { // if the monkey is on the box, then reach it if(states[i].Onbox) { reach(i); return Yes; } else { // monkey doesn't on the box but in the same place if(states[i].monkey == states[i].box) { climbOnbox(i); return nextStep(i+1); } // monkey doesn't on the box and not in the same place else { monkeyGoto(i, states[i].box); return nextStep(i+1); } } } // banana and box aren't in the same place else { // monkey on the box if(states[i].Onbox) { climbDownbox(i); return nextStep(i+1); } else { // monkey and box are in the same place if(states[i].monkey == states[i].box) { moveBox(i, states[i].banana); return nextStep(i+1); } // monkey and box aren't int the same place else { monkeyGoto(i, states[i].box); return nextStep(i+1); } } } } int nextStep1(int i) { while(i< maxStep) { // if the banana and box are in the same place if(states[i].banana == states[i].box) { // if the monkey is on the box, then reach it if(states[i].Onbox) { reach(i); return Yes; } else { // monkey doesn't on the box but in the same place if(states[i].monkey == states[i].box) { climbOnbox(i); i++; continue; } // monkey doesn't on the box and not in the same place else { monkeyGoto(i, states[i].box); i++; continue; } } } // banana and box aren't in the same place else { // monkey on the box if(states[i].Onbox) { climbDownbox(i); i++; continue; } else { // monkey and box are in the same place if(states[i].monkey == states[i].box) { moveBox(i, states[i].banana); i++; continue; } // monkey and box aren't int the same place else { monkeyGoto(i, states[i].box); i++; continue; } } } } if (i >= maxStep) { printf("Steps are too more, monkey can't go again!/n"); return No; } } int main(void) { init(); printf("nmonkey go to grasp the banana nownn"); nextStep1(0); printf("nTo reach the banana, monkey need to do %i stepsn", n); return 0; }
运行截图, 举几个例子,其它的可以自行尝试
三、简单分析
猴子摘香蕉问题是一个经典的人工智能算法题,主要考察对知识的表示和推理,可以设置多个初始状态,对猴子进行测试,具体的推理过程代码里已经详细讲解了,这里不做具体叙述。此外,注意初始状态的描述,当猴子与箱子不在同一位置时,猴子一定不在箱子上面。这里还写了递归和迭代的两种方法。
为了改变一下,本次注释采用英文形式,不便之处,多多见谅^_^
如果是广大的同学记得关注我哦,最近准备写实验的博客,包括大一,大二,大三的,如果大家有什么想让我写的博客,可以留言,我会在必要的时候把实验的内容发布在博客,供大家参考指教(^_^)
四、附上广大计科专业的人工智能本题的代码(非常不建议使用,bug特别多^_^,且难读懂)
#include <stdio.h> struct State { int monkey; /*-1:Monkey at A;0: Monkey at B;1:Monkey at C;*/ int box; /*-1:box at A;0:box at B;1:box at C;*/ int banana; /*Banana at B,Banana=0*/ int monbox; /*-1: monkey on the box;1: monkey the box;*/ }; struct State States [150]; char* routesave[150]; /*function monkeygoto,it makes the monkey goto the other place*/ void monkeygoto(int b,int i) { int a; a=b; if (a==-1) { routesave[i]="Monkey go to A"; States[i+1]=States[i]; States[i+1].monkey=-1; } else if(a==0) { routesave[i]="Monkey go to B"; States[i+1]=States[i]; States[i+1].monkey=0; } else if(a==1) { routesave[i]="Monkey go to C"; States[i+1]=States[i]; States[i+1].monkey=1; } else { printf("parameter is wrong"); } } /*end function monkeyygoto*/ /*function movebox,the monkey move the box to the other place*/ void movebox(int a,int i) { int B; B=a; if(B==-1) { routesave[i]="monkey move box to A"; States[i+1]=States[i]; States[i+1].monkey=-1; States[i+1].box=-1; } else if(B==0) { routesave[i] = "monkey move box to B"; States[i+1]=States[i]; States[i+1].monkey=0; States[i+1].box=0; } else if(B==1) { routesave[i] = "monkey move box to C"; States[i+1]=States[i]; States[i+1].monkey=1; States[i+1].box=1; } else { printf("parameter is wrong"); } } /*end function movebox*/ /*function climbonto,the monkey climb onto the box*/ void climbonto(int i) { routesave[i]="Monkey climb onto the box"; States[i+1]=States[i]; States[i+1].monbox=1; } /*function climbdown,monkey climb down from the box*/ void climbdown(int i) { routesave[i]="Monkey climb down from the box"; States[i+1]=States[i]; States[i+1].monbox=-1; } /*function reach,if the monkey,box,and banana are at the same place,the monkey reach banana*/ void reach(int i) { routesave[i]="Monkey reach the banana"; } /*output the solution to the problem*/ void showSolution(int i) { int c; printf ("%s n", "Result to problem:"); for(c=0; c<i+1; c++) { printf ("Step %d : %s n",c+1,routesave[c]); } printf("n"); } /*perform next step*/ void nextStep(int i) { int c; int j; if(i>=150) { printf("%s n", "steplength reached 150,have problem "); return; } for (c=0; c<i; c++) /*if the current state is same to previous,retrospect*/ { if(States[c].monkey==States[i].monkey&&States[c].box==States[i].box&&States[c].banana==States[i].banana&&States[c].monbox==States[i].monbox) { return; } } if(States[i].monbox==1&&States[i].monkey==0&&States[i].banana==0&&States[i].box==0) { showSolution(i); printf("Press any key to continue n"); getchar();/*to save screen for user,press any key to continue*/ return; } j=i+1; if(States[i].monkey==0) { if(States[i].box==0) { if(States[i].monbox==-1) { climbonto(i); reach(i+1); nextStep(j); /*monkeygoto(-1,i); nextStep(j); monkeygoto(0,i); nextStep(j); movebox(-1,i); nextStep(j); movebox(0,i); nextStep(j);*/ } else { reach(i+1); nextStep(j); /*climbdown(i); nextStep(j);*/ } } else if(States[i].box==1) { /*monkeygoto(-1,i); nextStep(j);*/ monkeygoto(1,i); nextStep(j); movebox(0,i); nextStep(j); climbonto(i); reach(i+1); nextStep(j); } else /*box==-1*/ { monkeygoto(-1,i); nextStep(j); movebox(0,i); nextStep(j); climbonto(i); reach(i+1); nextStep(j); } } /*end if*/ if(States[i].monkey==-1) { if(States[i].box==-1) { if(States[i].monbox==-1) { movebox(0,i); nextStep(j); climbonto(i); reach(i+1); nextStep(j); } else { climbdown(i); nextStep(j); movebox(0,i); nextStep(j); climbonto(i); reach(i+1); nextStep(j); } } else if(States[i].box==0) { monkeygoto(0,i); nextStep(j); climbonto(i); reach(i+1); nextStep(j); } else { monkeygoto(1,i); nextStep(j); movebox(0,i); nextStep(j); climbonto(i); reach(i+1); nextStep(j); } } /*end if*/ if(States[i].monkey==1) { if (States[i].box==1) { if(States[i].monbox==-1) { movebox(0,i); nextStep(j); climbonto(i); reach(i+1); nextStep(j); } else { climbdown(i); nextStep(j); movebox(0,i); nextStep(j); climbonto(i); reach(i+1); nextStep(j); } } else if(States[i].box==-1) { monkeygoto(-1,i); nextStep(j); movebox(0,i); nextStep(j); movebox(0,i); nextStep(j); climbonto(i); reach(i+1); nextStep(j); } else { monkeygoto(0,i); nextStep(j); movebox(0,i); nextStep(j); climbonto(i); reach(i+1); nextStep(j); } } /*end if*/ }/*end nextStep*/ int main() { States[0].monkey=-1; States[0].box=1; States[0].banana=0; States[0].monbox=-1; nextStep(0); }