Dijkstra在Python中的算法实现-它如何工作?

时间:2019-09-15 13:15:57

标签: python algorithm dijkstra

我可以在纸上使用Dijkstra算法找到以下最短路径:

  • 步骤1:将永久标签和顺序分配给起始节点

  • 步骤2:将临时标签分配给起始节点直接到达的所有节点

  • 第3步:选择最低的临时标签并将其设为永久标签

  • 第4步:向节点分配订单

  • 步骤5:为从新的永久节点直接到达的节点更新和分配临时标签

  • 第6步:重复第3、4和5步,直到将目标节点设为永久对象

我已经搜索了Python实现,其中许多都非常复杂或使用了我不熟悉的数据结构。最终我找到了下面的那个。我花了很多时间在Python可视化工具中追踪它的执行情况,我可以大致了解它的工作原理,但对我来说还没有点击。

有人可以解释一下代码与英语算法的关系吗?例如,“前辈”的概念与英文版中的“永久标签”有什么关系?

from math import inf

graph = {'a':{'b':10,'c':3},'b':{'c':1,'d':2},'c':{'b':4,'d':8,'e':2},'d':{'e':7},'e':{'d':9}}


def dijkstra(graph,start,goal):
    shortest_distance = {}
    predecessor = {}
    unseenNodes = graph
    infinity = inf
    path = []
    for node in unseenNodes:
        shortest_distance[node] = infinity
    shortest_distance[start] = 0

    # Determine which is minimum node. What does that mean?
    while unseenNodes:
        minNode = None
        for node in unseenNodes:
            if minNode is None:
                minNode = node
            elif shortest_distance[node] < shortest_distance[minNode]:
                minNode = node

        for edge, weight in graph[minNode].items():
            if weight + shortest_distance[minNode] < shortest_distance[edge]:
                shortest_distance[edge] = weight + shortest_distance[minNode]
                predecessor[edge] = minNode
        unseenNodes.pop(minNode)

    currentNode = goal
    while currentNode != start:
        try:
            path.insert(0,currentNode)
            currentNode = predecessor[currentNode]
        except KeyError:
            print('Path not reachable')
            break
    path.insert(0,start)
    if shortest_distance[goal] != infinity:
        print('Shortest distance is ' + str(shortest_distance[goal]))
        print('And the path is ' + str(path))


dijkstra(graph, 'a', 'b')

1 个答案:

答案 0 :(得分:1)

Dijkstra的算法与prim的最小生成树算法相同。像Prim的MST一样,我们以给定的源为根生成最短路径树。我们维护两组,一组包含最短路径树中包含的顶点,另一组包含尚未包含在最短路径树中的顶点。在算法的每个步骤中,我们都找到一个顶点,该顶点在另一个集合中(尚未包含),并且距源的距离最小。

    The following assertion was thrown during layout:
A RenderFlex overflowed by 0.966 pixels on the bottom.

User-created ancestor of the error-causing widget was:
  Container
  file:///Users/---/lib/presentation/profile_personal/profile_personal_screen.dart:89:16

The overflowing RenderFlex has an orientation of Axis.vertical.
The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the
RenderFlex to fit within the available space instead of being sized to their natural size.
This is considered an error condition because it indicates that there is content that cannot be
seen. If the content is legitimately bigger than the available space, consider clipping it with a
ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex,
like a ListView.
The specific RenderFlex in question is: RenderFlex#c07df OVERFLOWING:
  needs compositing
  creator: Column ← Padding ← DecoratedBox ← ConstrainedBox ← Container ← Padding ← Column ←
    _SingleChildViewport ← IgnorePointer-[GlobalKey#da8d9] ← Semantics ← _PointerListener ← Listener ←
    ⋯
  parentData: offset=Offset(1.0, 1.0) (can use size)
  constraints: BoxConstraints(w=727.6, h=29.0)
  size: Size(727.6, 29.0)
  direction: vertical
  mainAxisAlignment: center
  mainAxisSize: max
  crossAxisAlignment: center
  verticalDirection: down
◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤