墨小兰的玩具之野人与传教士

玩具描述:若干野人与若干传教士在河的一边,河上有一条一次只可以做两人的船。无论在船上还是在河的任意一岸,野人数量都不可以多于传教士数量。

使用了深度优先搜索的方法进行实现。

class State:
    def __init__(self, cannibals_left, missionaries_left, boat_left, cannibals_right, missionaries_right):
        self.cannibals_left = cannibals_left
        self.missionaries_left = missionaries_left
        self.boat_left = boat_left
        self.cannibals_right = cannibals_right
        self.missionaries_right = missionaries_right

    def is_valid(self):##合理性判断,野人在任何情况下都不能比传教士多
        if self.missionaries_left >= 0 and self.missionaries_right >= 0 \
                and self.cannibals_left >= 0 and self.cannibals_right >= 0 \
                and (self.missionaries_left == 0 or self.missionaries_left >= self.cannibals_left) \
                and (self.missionaries_right == 0 or self.missionaries_right >= self.cannibals_right):
            return True
        return False

    def is_goal(self):#目标状态
        return self.cannibals_left == 0 and self.missionaries_left == 0

    def __eq__(self, other):#判断所有必须的条件是否成立
        return self.cannibals_left == other.cannibals_left and self.missionaries_left == other.missionaries_left \
               and self.boat_left == other.boat_left and self.cannibals_right == other.cannibals_right \
               and self.missionaries_right == other.missionaries_right

    def __hash__(self):
        return hash((self.cannibals_left, self.missionaries_left, self.boat_left, self.cannibals_right, self.missionaries_right))


def successors(state):#处理函数
    children = []
    if state.boat_left:  # 船在左侧
        for i in range(3):
            for j in range(3):
                if 1 <= i + j <= 2:#状态合理性判断
                    child = State(state.cannibals_left - i, state.missionaries_left - j, not state.boat_left,
                                  state.cannibals_right + i, state.missionaries_right + j)
                    if child.is_valid():
                        children.append(child)
    else:  #船在右侧
        for i in range(3):
            for j in range(3):
                if 1 <= i + j <= 2:
                    child = State(state.cannibals_left + i, state.missionaries_left + j, not state.boat_left,
                                  state.cannibals_right - i, state.missionaries_right - j)
                    if child.is_valid():
                        children.append(child)
    return children


def dfs(current_state, visited_states):
    if current_state.is_goal():#达到目标
        return [current_state]
    visited_states.add(current_state)#搜索过的状态集
    for child in successors(current_state):
        if child not in visited_states:
            path = dfs(child, visited_states)
            if path:
                return [current_state] + path
    return None


def solve():
    initial_state = State(3, 3, True, 0, 0)
    visited_states = set()
    return dfs(initial_state, visited_states)


solution = solve()
if solution:
    for i, state in enumerate(solution):
        print(f"Step {i}:")
        print(f"Left: {state.cannibals_left} cannibals, {state.missionaries_left} missionaries")
        print(f"Right: {state.cannibals_right} cannibals, {state.missionaries_right} missionaries")
        print("--------------")
else:
    print("No solution exists!")

本文仅为娱乐之作,如有错误欢迎指出。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值