农夫过河 python 回溯

wc = ['wolf','sheep','ve'] #西岸初始状态
ec = ['None'] #东岸初始状态

result = [] #记录成功方案的轨迹
table = [] #搜索过程的备忘录

farmerloc = 'wc' #农夫的位置
res = 0 #成功方案个数

def backtrack(wc, ec, farmerloc, lastdelivery, table): #lastdelivery是上次运输的东西, 
    global res

    for i in result: #检查该状态是否在已成功的案例中出现过
        if [wc,ec,farmerloc,lastdelivery] in i:
            return
        
    if len(ec) == 4: #如果东岸列表已有4个(包括'None')元素则结束
        res += 1
        result.append(table)
        return
    

    #检查非法状态
    if 'wolf' in wc and 'sheep' in wc and farmerloc == 'ec':
        return
    elif 'wolf' in ec and 'sheep' in ec and farmerloc == 'wc':
        return
    elif 'sheep' in wc and 've' in wc and farmerloc == 'ec':
        return
    elif 'sheep' in ec and 've' in ec and farmerloc == 'wc':
        return

    #回溯过程
    if farmerloc == 'wc':
        for i in wc[:]:
            if i == lastdelivery:
                continue

            table.append([wc, ec, farmerloc, i])
            wc.remove(i)
            ec.append(i)
            farmerloc = 'ec'
            backtrack(wc[:], ec[:], farmerloc, i, table[:])
            wc.append(i)
            ec.remove(i)
            farmerloc = 'wc'
            
    if farmerloc == 'ec':
        for i in ec[:]:
            if i == lastdelivery:
                continue

            if i == 'None':
                table.append([wc, ec, farmerloc, i])
                farmerloc = 'wc'
                backtrack(wc[:], ec[:], farmerloc, i, table[:])
                farmerloc = 'ec'

            else:
                table.append([wc, ec, farmerloc, i])
                ec.remove(i)
                wc.append(i)
                farmerloc = 'wc'
                backtrack(wc[:], ec[:], farmerloc, i, table[:])
                ec.append(i)
                wc.remove(i)
                farmerloc = 'ec'
     
backtrack(wc, ec, farmerloc, 'None', table[:])
print(res)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值