《人工智能》实验一

猴子摘香蕉

# -*- coding: utf-8 -*-

'''
猴子摘香蕉问题
'''

'''
monkey  Location of monkey
box	    Location of box
onbox	0:monkey not on	1:monkey on the box
pick_banana  1: banana picked
banana  Location of banana
'''

class State:
    def __init__(self, monkey=-1, onbox=0 , box=-1 , pick_banana=0, banana=-1):
        self.monkey = monkey
        self.monbox = onbox
        self.box = box
        self.pick_banana = pick_banana
        self.banana = banana

# 猴子水平移动
def goto(self, step):
    print("步数" + str(step) + ":猴子从" + str(self.monkey) + "移动到" + str(self.box) )
    self.monkey = self.box
    return self

# 猴子推箱子
def pushbox(self, step):
    print("步数" + str(step) + ":猴子将箱子从" + str(self.box)+ "移动到" + str(self.banana) )
    self.onbox = self.banana
    self.box = self.banana
    return self

def climbbox(self, step):
    print("步数" + str(step) + ":猴子爬到箱子上去")
    self.monbox = 1
    return self

def grasp(self, step):
    print("步数" + str(step) + ":猴子摘到香蕉")
    self.pick_banana = 1
    return self

def action(self):
    step = 0
    # 猴子和箱子不在一起
    if self.monkey != self.box:
        step = step + 1
        goto(self, step)
    # 箱子和香蕉不在一起
    if self.box != self.banana:
        step = step + 1
        pushbox(self, step)

    step = step + 1
    climbbox(self, step)
    step = step + 1
    grasp(self, step)


if __name__ == '__main__':
    a = input("输入猴子的位置:")
    b = input("输入箱子的位置:")
    c = input("输入香蕉的位置:")

    sta = State(monkey=a, box=b, banana=c)
    action(sta)

传教士野人过河问题

# 计算船的合法状态空间
def get_states(k):  # 船准备跑第k趟
    global n, m, x

    if k % 2 == 0:  # 从左到右,只考虑原左岸人数
        s1, s2 = n - sum(s[0] for s in x), n - sum(s[1] for s in x)
    else:  # 从右到左,只考虑原右岸人数(将船的历史状态累加可得!!!)
        s1, s2 = sum(s[0] for s in x), sum(s[1] for s in x)
    for i in range(s1 + 1):
        for j in range(s2 + 1):
            if 0 < i + j <= m and (i * j == 0 or i >= j):
                # 生成船的合法状态
                yield [(-i, -j), (i, j)][k % 2 == 0]


# 冲突检测
def conflict(k):  # 船开始跑第k趟
    global n, m, x
    # 若船上载的人与上一趟一样(会陷入死循环!!!!)
    if k > 0 and x[-1][0] == -x[-2][0] and x[-1][1] == -x[-2][1]:
        return True
    # 任何时候,船上传教士人数少于野人,或者无人,或者超载(计算船的合法状态空间时已经考虑到了。)
    # 任何时候,左岸传教士人数少于野人
    if 0 < n - sum(s[0] for s in x) < n - sum(s[1] for s in x):
        return True
    # 任何时候,右岸传教士人数少于野人
    if 0 < sum(s[0] for s in x) < sum(s[1] for s in x):
        return True
    return False  # 无冲突

def dfs(k):  # 船准备跑第k趟
    global n, m, x, suc, ans
    if suc:
        return x  # 终止所有递归
    if n - sum(s[0] for s in x) == 0 and n - sum(s[1] for s in x) == 0:  # 左岸人数全为0
        print(x)
        for i in range(len(x)):
            if(i%2 == 0):
                print("第%d趟:从左岸到右岸%d个传教士、%s个野人" %(i+1, x[i][0], x[i][1]) )
            else:
                print("第%d趟:从右岸到左岸%d个传教士、%d个野人" %(i+1, -x[i][0], -x[i][1]) )
        suc = True
    else:
        for state in get_states(k):  # 遍历船的合法状态空间
            x.append(state)
            if not conflict(k):
                dfs(k + 1)  # 深度优先
            x.pop()  # 回溯

n = 3  # n个传教士、n个野人
m = 2  # 船能载m人
x = []  # 一个解,就是船的一系列状态
X = []  # 一组解
suc = False  # 全局终止标志
ans = []

# 测试
dfs(0)
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值