Python 解决Dijkstra';s算法-使用两条边传递成本/父项

Python 解决Dijkstra';s算法-使用两条边传递成本/父项,python,algorithm,graph,dijkstra,Python,Algorithm,Graph,Dijkstra,我有一个这样的图表: # graph table graph = {} graph['start'] = {} graph['start']['a'] = 5 graph['start']['b'] = 2 graph['a'] = {} graph['a']['c'] = 4 graph['a']['d'] = 2 graph['b'] = {} graph['b']['a'] = 8 graph['b']['d'] = 7 graph['c'] = {} graph['c']['d'

我有一个这样的图表:

# graph table
graph = {}
graph['start'] = {}
graph['start']['a'] = 5
graph['start']['b'] = 2

graph['a'] = {}
graph['a']['c'] = 4
graph['a']['d'] = 2 

graph['b'] = {}
graph['b']['a'] = 8
graph['b']['d'] = 7

graph['c'] = {}
graph['c']['d'] = 6
graph['c']['finish'] = 3

graph['d'] = {}
graph['d']['finish'] = 1
graph['finish'] = {}

我正试图找到从
S
F
的最快方法

在本书的第一个示例中,只有一条边连接到一个节点,例如,在本示例中,节点
D
具有3个权重,并且使用了
成本
表:

costs = {}
infinity = float('inf')
costs['a'] = 5
costs['b'] = 2
costs['c'] = 4 
costs['d'] = # there is 3 costs to node D, which one to select?
costs['finish'] = infinity
和一张家长表:

parents = {}
parents['a'] = 'start' # why not start and b since both `S` and `B` can be `A` nodes parent?
parents['b'] = 'start'
parents['c'] = 'a'
parents['d'] =  # node D can have 3 parents
parents['finish'] = None
但这也是可行的,我的意思是不会抛出错误,所以我只需要从第一个节点
S
中命名父节点吗

parents = {}
parents['a'] = 'start' 
parents['b'] = 'start'
parents['finish'] = None
守则:

processed = []

def find_lowest_cost_node(costs):
    lowest_cost = float('inf')
    lowest_cost_node = None

    for node in costs:
        cost = costs[node]

        if cost < lowest_cost and node not in processed:
            lowest_cost = cost
            lowest_cost_node = node
    return lowest_cost_node



node = find_lowest_cost_node(costs)

while node is not None:
  cost = costs[node]
  neighbors = graph[node]
  for n in neighbors.keys():
      new_cost = cost + neighbors[n]
      if costs[n] > new_cost:
          costs[n] = new_cost
          parents[n] = node
  processed.append(node)
  node = find_lowest_cost_node(costs)


def find_path(parents, finish):
  path = []
  node = finish
  while node:
      path.insert(0, node)
      if parents.__contains__(node):
          node = parents[node]
      else:
          node = None
  return path


path = find_path(parents, 'finish')
distance = costs['finish']

print(f'Path is: {path}')
print(f'Distance from start to finish is: {distance}')
我的错误在哪里?我应该如何将
成本
父节点
添加到可以从多个节点访问的节点

编辑
我相信这不是解决此问题的最佳方法,欢迎提供最佳实践解决方案/建议。

您无需使用超过
成本['start']=0
或超过
家长={}
的家长字典来初始化成本表。这就是您的算法将为您创建的内容

您需要做的唯一其他更改是while循环。它只需要检查之前是否已检测到新节点。如果是这样,那么我们检查新路径是否更短,并根据需要进行更新;如果没有,那么我们就建立新的路径

while node is not None:
  cost = costs[node]
  neighbors = graph[node]
  for n in neighbors.keys():
      new_cost = cost + neighbors[n]
      if n in costs:
          if costs[n] > new_cost:
              costs[n] = new_cost
              parents[n] = node
      else:
          costs[n] = new_cost
          parents[n] = node
  processed.append(node)
  node = find_lowest_cost_node(costs)

我认为有更简洁的方法来处理图形,但这是使代码按要求工作所需的最小更改。希望对你有帮助

您不必填写成本表,这是由算法生成的。看一看,我已经用你的图表试过了,它提供了正确的结果。所以在做了
父项
成本
之后,我得到了一个错误,因为没有
成本['finish']
。如果我删除它,那么我会得到相同的答案。你确实需要包括
成本['start']=0
,正如我上面所说的:P
KeyError:'finish'
如果我只离开
parents={}
。嗯,我不确定我们的代码有什么不同。我的完整文件在这里:它输出:路径是:['start','a','d','finish']从开始到结束的距离是:8
while node is not None:
  cost = costs[node]
  neighbors = graph[node]
  for n in neighbors.keys():
      new_cost = cost + neighbors[n]
      if n in costs:
          if costs[n] > new_cost:
              costs[n] = new_cost
              parents[n] = node
      else:
          costs[n] = new_cost
          parents[n] = node
  processed.append(node)
  node = find_lowest_cost_node(costs)