Grokking algorithms(第七章)Dijkstra’s algorithm

上一章的广度优先,可以找到最短的路径,本章的算法,可以找到最快的路径,如下图

 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

猜你喜欢

转载自blog.csdn.net/Gussss/article/details/95791415
今日推荐