猴子摘香蕉问题

一、问题描述

        利用一阶谓词逻辑求解猴子摘香蕉问题:房内有一个猴子,一个箱子,天花板上挂了一串香蕉,其位置如图1所示,猴子为了拿到香蕉,它必须把箱子搬到香蕉下面,然后再爬到箱子上。请定义必要的谓词,列出问题的初始化状态(即下图所示状态),目标状态(猴子拿到了香蕉,站在箱子上,箱子位于位置b)。

猴子摘香蕉问题_第1张图片

二、迟来的的代码

#include 

#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 banana\n");
    n++;
}

// monkey go to location
void monkeyGoto(int i, char location)
{
	printf("monkey go to %c\n", 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 box\n");
    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 box\n");
    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 %c\n", 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 now\n\n");
    nextStep1(0);
    printf("\nTo reach the banana, monkey need to do %i steps\n", n);

	return 0;
}



运行截图, 举几个例子,其它的可以自行尝试

猴子摘香蕉问题_第2张图片

 猴子摘香蕉问题_第3张图片

 猴子摘香蕉问题_第4张图片

三、简单分析

        猴子摘香蕉问题是一个经典的人工智能算法题,主要考察对知识的表示和推理,可以设置多个初始状态,对猴子进行测试,具体的推理过程代码里已经详细讲解了,这里不做具体叙述。此外,注意初始状态的描述,当猴子与箱子不在同一位置时,猴子一定不在箱子上面。这里还写了递归和迭代的两种方法。

        为了改变一下,本次注释采用英文形式,不便之处,多多见谅^_^

        如果是广大的同学记得关注我哦,最近准备写实验的博客,包括大一,大二,大三的,如果大家有什么想让我写的博客,可以留言,我会在必要的时候把实验的内容发布在博客,供大家参考指教(^_^)

四、附上广大计科专业的人工智能本题的代码(非常不建议使用,bug特别多^_^,且难读懂)

#include 
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=150)
    {
		printf("%s  \n", "steplength reached 150,have problem ");
        return;
    }
	for (c=0; c

你可能感兴趣的