猴子摘香蕉问题

一、问题描述

        利用一阶谓词逻辑求解猴子摘香蕉问题:房内有一个猴子,一个箱子,天花板上挂了一串香蕉,其位置如图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);
}

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>