Code | 野人与传教士

本文探讨了经典的传教士与野人过河问题,并通过算法寻找最优解决方案。该问题要求三名传教士和三名野人利用一艘仅能容纳两人的小船过河,且任何时候任一岸的野人数不能超过传教士数,否则传教士将被野人吃掉。
'''
问题描述:三个野人,三个传教士,一艘船,船上至多有两人,在一起的野人数不能超过传教士,否则传教士被吃。
状态=[传教士数,野人数,船是否在本岸] 
动作=[传教士上船人数,野人上船人数]

变量说明:
*state_route:[[state],[action1],[action2]] 用以描述当前state,是经过怎样的动作序列得到。
*state_table: [state_route, stateroute...] 未探索的状态及路径列表
*searched_table:[state,state...] 已探索的状态列表

'''

def state_transfer(state_route, action):
    route = state_route.copy()
    state = route[0]
    new_state = [0, 0, 0]

    if state[2] == 1:
        if state[0] < action[0] or state[1] < action[1]:
            return False
        else:
            new_state[0] = state[0]-action[0]
            new_state[1] = state[1]-action[1]
            new_state[2] = 1-state[2]
    else:
        if 3-state[0] < action[0] or 3-state[1] < action[1]:
            return False
        else:
            new_state[0] = state[0]+action[0]
            new_state[1] = state[1]+action[1]
            new_state[2] = 1-state[2]

    if new_state[0] < new_state[1] and new_state[0] != 0:
        return False
    if 3-new_state[0] < 3-new_state[1] and 3-new_state[0] != 0:
        return False
    route[0] = new_state
    route.append(action)
    return route


def main():
    state_table = []
    state_route = []
    target = [0,0,0]
    state_init = [3, 3, 1]
    state_route.append(state_init.copy())
    state_table.append(state_route.copy())
    searched_table = []
    action = [[0,1],[1,0],[0,2],[2,0],[1,1]]

    while state_table != []:
        if state_table[0][0] not in searched_table:
            for i in range(5):
                state_route = state_transfer(state_table[0], action[i])
                if state_route is False:
                    continue
                if state_route[0] == target:
                    print(state_route)
                    break
                state_table.append(state_route)
            searched_table.append(state_table[0][0])
        state_table.pop(0)


if __name__ == "__main__":
    main()

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值