玩具描述:若干野人与若干传教士在河的一边,河上有一条一次只可以做两人的船。无论在船上还是在河的任意一岸,野人数量都不可以多于传教士数量。
使用了深度优先搜索的方法进行实现。
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!")
本文仅为娱乐之作,如有错误欢迎指出。