上一章的广度优先,可以找到最短的路径,本章的算法,可以找到最快的路径,如下图
Working with Dijkstra’s algorithm
Terminology
graph中每一条edge都有一个weight,那么叫weighted graph,没有edge的话,就叫unweighted graph.
在unweighted graph中找出最短路径,使用breadth-first搜索。
在weighted graph中找出最短路径,使用Dijkstra 算法
Negative-weight edges
又edge为负的情况,如下图,lp到poster为-7
不能用Dijkstra’s 算法,可以使用Bellman-Ford algorithm
Implementation
下图为算法作用的图
cost of the node的定义:The cost is how long it takes to get to that node from the start.(从start点到node点的距离)
假如需要更新node B邻域(B指向Fin,fin为B的邻域,因为fin没有箭头指出去,所以fin没有邻域):以node A举例:Here, you’re calculating how long it would take to get to node A if you went Start > node B > node A, instead of Start > node A.(是计算从start->B->A的cost)
第一步 定义graph
graph = {}
graph[“start”] = {}
graph[“start”][“a”] = 6
graph[“start”][“b”] = 2
graph[“a”] = {}
graph[“a”][“fn”] = 1
graph[“b”] = {}
graph[“b”][“a”] = 3
graph[“b”][“fn”] = 5
graph[“fn”] = {} ##The fnish node doesn’t have any neighbors.
可视化上面的代码,如下图
第二部,定义cost
infnity = float(“inf”)
infnity = float(“inf”)
costs = {}
costs[“a”] = 6
costs[“b”] = 2
costs[“fn”] = infnity
可视化如下图所示:
第三部,定义parents:
parents = {}
parents[“a”] = “start”
parents[“b”] = “start”
parents[“fn”] = None
可视化如下图
第四部,定义一个列表,里面存储已经处理过的node
processed = []
下面是整个算法的定义
def fnd_lowest_cost_node(costs):
lowest_cost = float(“inf”)
lowest_cost_node = None
for node in costs: Go through each node.
cost = costs[node]
if cost < lowest_cost and node not in processed:
lowest_cost = cost … set it as the new lowest-cost node.
lowest_cost_node = node
return lowest_cost_node
这里需要注意cost这里是一个字典,如下代码相等,print的都是a,b,fin
for node in costs:
print (node)
for node in costs.keys():
print (node)
node = fnd_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 = fnd_lowest_cost_node(costs)
编程实现例子
#define graph
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']['finish'] = 3
graph['c']['d'] = 6
graph['d'] = {}
graph['d']['finish'] = 1
graph['finish'] = {}
#define costs
infnity = float('inf')
costs = {}
costs['a'] = 5
costs['b'] = 2
costs['c'] = infnity
costs['d'] = infnity
costs['finish'] = infnity
#define parents
parents = {}
parents['a'] = 'start'
parents['b'] = 'start'
parents['finish'] = None
#define processed
processed = []
def find_lowest_cost_node(costs):
lowestCost = infnity
lowestNode = None
for node in costs.keys():
if costs[node]<lowestCost and node not in processed:
lowestCost = costs[node]
lowestNode = node
return lowestNode
node = find_lowest_cost_node(costs)
while node :
cost = costs[node]
neighbors = graph[node]
for neighbor in neighbors.keys():
currentCost = cost+neighbors[neighbor]
if currentCost<costs[neighbor]:
costs[neighbor] = currentCost
parents[neighbor] = node
processed.append(node)
node = find_lowest_cost_node(costs)
print ('cost of finish is {}'.format(costs['finish']))
由上图中可以看出,finish的cost为8,并且finish的parent为d ,然后d的parent为a,a的parent为start,因此可以得出结论
start->a->d->finish,中间所得出的cost正好为8