背景简介/问题描述
实验要求参照课程第二部分讲授的知识表示方法求解猴子摘香蕉或野人问题,在此我选择解决猴子摘香蕉问题,具体问题描述如下:
一个房间里,天花板上挂有一串香蕉,有一只猴子可在房间里任意活动(到处走动,推移箱子,攀登箱子等)。设房间里还有一只可被猴子移动的箱子,且猴子登上箱子时才能摘到香蕉,问猴子在某一状态下(设猴子位置为A,香蕉位置在B,箱子位置为C),如何行动可摘取到香蕉。
算法介绍
2.1 算法实现思路
我们要实现以下步骤:让猴子得到香蕉,但是直接跳够不到,必须站在箱子上才能取到。
这个案例共有以下几种情况,猴子香蕉箱子在同一处,猴子香蕉在同一处,香蕉箱子在同一出,还有三者均不在同一处,但不论是哪种情况,我们需要清楚一点,那就是说,就算是香蕉和猴子在同一位置,猴子也无法直接获得香蕉,因此我们
第一步必须需要先找到箱子,然后再去搬着箱子移动到香蕉处。
2.2 案例谓词逻辑
本案例中有以下四个谓词逻辑:
Run(monkey,box)代表猴子去搬箱子;
Getbox(monkey,box)代表猴子得到了箱子;
Run(monkey,banana)代表了猴子搬着箱子去找香蕉;
Getbanana(monkey,banana)代表猴子拿到了香蕉。
以下将用c语言实现此代码(后附python实现)。
算法实现
3.1 c语言代码实现
环境为codeblocks,Windows 11 x64系统。
代码思路见上2.1,具体代码如下:
#include <stdio.h>
#include <stdlib.h>
int main(){
void gobox(int a,int b);
void getbox();
void findbanana(int a,int b);
void getbanana();
int monkey,banana,box;
printf("请依次输入猴子,香蕉,箱子 的位置\n");
printf("猴子的位置:");
scanf("%d",&monkey);
printf("香蕉的位置:");
scanf("%d",&banana);
printf("箱子的位置:");
scanf("%d",&box);
printf("-----------------------------------\n");
if(monkey!=box){
printf("猴子够不到香蕉,要先去搬箱子:");
gobox(monkey,box);
getbox();
if(box!=banana){
printf("猴子需要搬着箱子去找到香蕉:");
findbanana(banana,box);
getbanana();
}
else{
printf("香蕉就在箱子的上面\n");
getbanana();
}
}
else{
printf("箱子就在猴子旁边,猴子拿到了箱子");
getbox();
if(box!=banana){
printf("猴子需要搬着箱子去找到香蕉:");
findbanana(banana,box);
getbanana();
}else{
printf("香蕉就在箱子的上面\n");
getbanana();
}
}
}
void gobox(int a,int b){
int flag;
flag = b - a;
if(flag>0){
printf("Run(monkey,box)\n");
printf("猴子需要向右移动%d步拿到箱子\n",flag);
}else{
printf("Run(monkey,box)\n");
printf("猴子需要向左移动%d步拿到箱子\n",-flag);
}
}
void findbanana(int a,int b){
int flag;
flag=b-a;
if(flag>0){
printf("Run(monkey,banana)\n");
printf("猴子需要向左搬着箱子移动%d步找到香蕉\n",flag);
}else{
printf("Run(monkey,banana)\n");
printf("猴子需要向右搬着箱子移动%d步找到香蕉\n",-flag);
}
}
void getbox(){
printf("猴子拿到了箱子:");
printf("Getbox(monkey,box)\n");
}
void getbanana(){
printf("猴子踩在箱子上拿到了香蕉:");
printf("Getbanana(monkey,banana)\n");
}
3.2 运行示例结果
讨论及结论
4.1 c语言代码各个情况讨论
排除对向左和向右移动的讨论后,情况分为四种:三者均不在同一位置;猴子和箱子在同一位置,香蕉不同;猴子和香蕉在同一位置,箱子不同;以及三者均在同一位置。
下面我分别用猴子,香蕉,箱子位置为3,8,5;3,5,3;3,3,1;6,6,6来进行运行示例展示。
4.2 各个情况运行结果
- 猴子,香蕉,箱子位置为3,8,5
- 猴子,香蕉,箱子位置为3,5,3
- 猴子,香蕉,箱子位置为3,3,1
- 猴子,香蕉,箱子位置为6,6,6
参考文献
[1] 卡卡西今天怎么样.人工智能谓词逻辑--猴子摘香蕉问题.2022-03-22.[DB/OL].https://blog.csdn.net/weixin_52212950/article/details/123662272
附录(python实现)
(MonkeyPos,BananaPos,BoxPos)=input("请分别输入猴子、香蕉和箱子的位置坐标a、b、c(中间用英文逗号分隔):").split(",")
step=1 # 用于记录当前是第几步
# 第一步:猴子走到箱子处,需要判断是向左走还是向右走。但是出于鲁棒性考虑,如果猴子本身和箱子在同一个位置,那么就不需要进行这一步。
gap1=eval(BoxPos)-eval(MonkeyPos)
if(gap1>0):
print("第"+str(step)+"步:猴子向右走"+str(gap1)+"米到达箱子处。")
step=step+1
elif(gap1<0):
print("第" + str(step) + "步:猴子向左走" + str(-gap1) + "到达箱子处。")
step=step+1
# 第二步:猴子把箱子推到香蕉的正下方,同样需要判断是向左走还是向右走。但是出于鲁棒性考虑,可能香蕉刚好位于箱子的正上方,那么就不需要这一步
gap2=eval(BananaPos)-eval(BoxPos)
if(gap2>0):
print("第" + str(step) + "步:猴子向右推着箱子走" + str(gap2) + "到达香蕉的正下方。")
step=step+1
elif(gap2<0):
print("第" + str(step) + "步:猴子向左推着箱子走" + str(-gap2) + "到达香蕉的正下方。")
step = step + 1
# 第三步:这一步不可省略,即猴子爬上箱子后摘取香蕉
print("第" + str(step) + "步:猴子爬上箱子并跳起来摘到香蕉。")