微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何应用蛮力方法来解决传教士和食人族问题?

如何解决如何应用蛮力方法来解决传教士和食人族问题?

我正在尝试使用蛮力 (generate and test) 方法解决 Missionaries and Cannibals problem

我有这个元组列表,它代表在给定状态下执行的操作:

# [(take one missionary,take no cannibals),(take no cannibals,take one missionary),etc]
actions = [(1,0) (0,1),(1,(2,0),(0,2)]

我有这个起始状态:

# 3 cannibals and missionaries on the left side
initial_state = [3,3,Left]

我有这个目标状态:

 # 3 cannibals and missionaries on the right side
goal_state= [0,Right]

我编写了以下函数生成状态并测试每个生成状态的有效性:

def valid_state(a_state):
    if (a_state[1] >= 0 and a_state[0] >= 0) and not (
            do_cannibals_outnumber_missionaries(a_state[0],a_state[1])):
        return True
    else:
        return False

def generate_states():
    for i in moves:
        a_state = [init_state[0] - i[0],init_state[1] - i[1],init_state[2] + i[0],init_state[3] + i[1],not init_state[4]] #cross to right side of river

        if valid_state(a_state):   #this weeds out invalid states
            visited.append(a_state)   #this list contains all the visited,valid states
            

当我以初始状态运行我的代码时,我得到:

[[3,2,1,Right],[2,[3,Right]]

如何应用相同的逻辑从这些状态中生成更多状态(即,将传教士和食人者带到左侧并存储下一系列有效状态 - 依此类推,直到我达到目标状态)?

我觉得这可以与递归一起使用...我不是在寻找高度优化的解决方案。

解决方法

找到所有解的递归程序的一般形式如下:

all_paths = []
def move_boat(state,history=None):
    if history is None:
        history = []
    # if len(history) > 50: return
    if is_final_state(state):  # are we finished?
        all_paths.append(history + [state])
    else:
        for new_state in generate_next_states(state,actions):  # generate all possible next states
            if not is_legal_state(new_state):
                continue
            move_boat(new_state,history + [state])

因为有可能通过生成使同一个人来回移动的动作进入无限循环,所以您可能应该进行一些安全检查,例如注释掉的 if 语句。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。