Use python to solve the problem of crossing the river

Problem description:
3 antelopes and 3 lions are preparing to cross the river by boat. There is a small boat on the river that can accommodate 2 animals. However, if the number of lions on both sides of the river is greater than the number of antelopes, the antelopes will be eaten. Find a way to transport all the animals across the river safely.
(There is a video explanation at the end of the article!)
 

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)

Use python to solve the problem of antelope and lion crossing the river

Guess you like

Origin blog.csdn.net/weixin_64890968/article/details/131721471