代码改变世界

最快路径与狄克斯特拉

2019-08-24 21:43  DataBases  阅读(281)  评论(0编辑  收藏  举报

要找出从起点到终点耗时最短的路径需要使用狄克斯特拉算法。

狄克斯特拉算法用于找出最快的路径。

狄克斯特拉算法只适用于有向无环图DAG(directed acyclic graph)。 

狄克斯特拉算法用于每条边都 有关联数字的图,这些数字为权重。

带权重的图称为加权图,不带权重的图称为非加权图;

要计算非加权图中的最短路径,可使用广度优先搜索;

要计算加权图中的最短路径,可使用狄克斯特拉算法。

负权边的图不能使用迪克斯特拉算法,负权边会导致这种算法不管用。

在狄克斯特拉算法中给图的每条边都分配了一个数字或权重,因此,狄克斯特拉算法找出的是总权重最小的路径。

节点的开销:从起点出发前往该节点需要的耗时(代价)。

狄克斯特拉算法的实现思路:
1.找出代价最小的节点,即可在最短时间内到达的节点。

2.对该节点的邻居,检查是否有前往他们的更短路径,如果有,就更新其开销。

3.重复上述过程,直到对图中每个节点都这样做了。

4.计算最终路径。

 

# 图结构散列表
graph = {}
graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2

graph["a"] = {}
graph["a"]["fin"] = 1
graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["fin"] = 5
graph["fin"] = {}
# costs散列表
infinity = float("inf")
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity
# 存储父节点的散列表
parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = 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


def dijkstra():
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)
print("Costs from the start to each node:")
print(costs)


if __name__ == '__main__':
dijkstra()