问题描述:
3只羚羊和3只狮子准备乘船过河,河边有一艘能容纳2只动物的小船,但是,如果两侧河岸上的狮子数量大于羚羊数量,羚羊就会被吃掉。找到运送办法,使得所有动物都能安全渡河。
(文章最后有视频讲解!)
from pythonds.basic import Queue
def river_crossing():
"""
1艘船只能容纳2只动物
创建一个列表用于存放运输的可能情况
"""
delivery = [(1, 0), (0, 1), (1, 1), (2, 0), (0, 2)]
"""
3只羚羊和3只狮子过河
0和1用于区分船在a岸还是b岸
"""
A = (3, 3, 1)
B = (0, 0, 0)
mygraph = [] # 为接下来图的绘制存储从哪个节点到哪个节点需要什么步骤
myqueue = Queue()
myqueue.enqueue((A, B)) # 将合法的河岸状态入队
possible_A = [A] # 存放a岸出现过的情况
# 通过广度优先:从当前状态开始,遍历所有可能的决策,进行状态跳转
while True:
"""
用队列来存储合法的河岸状态改变后的状态
"""
A, B = myqueue.dequeue()
# 当a岸没有小动物,运输完成
if A == (0, 0, 0):
break
for i in delivery:
"""
一次(从a岸到b岸的)运输
动物数量对应发生改变
河岸状态也发生改变
船在A岸,则A岸狮子、羊的数量减少,B岸狮子、羊的数量增加;
船在B岸,则A岸狮子、羊的数量增加,B岸狮子、羊的数量减少;
"""
if A[2] == 1:
transform_A = (A[0] - i[0], A[1] - i[1], A[2] - 1)
transform_B = (B[0] + i[0], B[1] + i[1], B[2] + 1)
else:
transform_A = (A[0] + i[0], A[1] + i[1], A[2] + 1)
transform_B = (B[0] - i[0], B[1] - i[1], B[2] - 1)
"""
在有羊的情况下,如果狮子大于羊,则吃掉
如果运送后,动物的数量小于0或者大于总数表示不合法
"""
if transform_A[0] and transform_A[0] < transform_A[1]:
continue
elif transform_B[0] and transform_B[0] < transform_B[1]:
continue
elif transform_A[0] < 0 or transform_A[0] > 3 or transform_A[1] < 0 or transform_A[1] > 3:
continue
else:
# 去重复
if transform_A in possible_A:
continue
else:
possible_A.append(transform_A)
myqueue.enqueue((transform_A, transform_B))
# addEdge(fromVert, toVert, weight) 添加带权的有向边
# mygraph.addEdge(A, transform_A, i)
mygraph.append((A, transform_A, i))
return mygraph, possible_A
"""
该函数用于构造图的邻接表
"""
def build_graph(nodes, edges):
graph = {}
for i in nodes:
graph[i] = {}
for j in edges:
q = j[0]
w = j[1]
e = j[2]
graph[q][w] = e
return graph
"""
以a岸为基准,输出a岸动物数量变化及变化过程
"""
def find_way(graph, nodes):
a = (0, 0, 0)
while a != (3, 3, 1):
b = get_key(graph, a, nodes)
print(a, '<--', graph[b][a], '<---', b)
a = b
def get_key(dict, value, nodes):
for i in nodes:
for j in dict[i]:
if j == value:
return i
if __name__ == '__main__':
edges, nodes = river_crossing()
# print(edges)
# print(nodes)
graph = build_graph(nodes, edges)
# print(graph)
find_way(graph, nodes)
用python解决羚羊狮子的过河问题