《算法图解》日志四(python)(狄克斯特拉算法)

介绍

规则

  1. 找出最便宜的节点,即最短时间内前往的节点
  2. 对于该节点的邻居,检查是否有前往他们的最短路径,如果有,就更新其开销
  3. 重复这个过程,知道对图中的每个节点都这样做了
  4. 计算最终路径

知识站点

负权边

狄克斯特拉算法不支持包含负边权的图,因为,狄克斯特拉算法这样假设:对于处理过的海报节点,没有前往该节点的更短的路径。包含负边权的图,可使用贝尔曼-福德算法(bellman-Ford algorithm)。

作用

狄克斯特拉算法用于加权图中查找最短路径

定义

Dijkstra算法一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表的方式,这里均采用永久和临时标号的方式。注意该算法要求图中不存在负权边。

实现

python代码

 1 # the graph
 2 graph = {}
 3 graph["start"] = {}
 4 graph["start"]["a"] = 6
 5 graph["start"]["b"] = 2
 6 
 7 graph["a"] = {}
 8 graph["a"]["fin"] = 1
 9 
10 graph["b"] = {}
11 graph["b"]["a"] = 3
12 graph["b"]["fin"] = 5
13 
14 graph["fin"] = {}
15 
16 # the costs table
17 infinity = float("inf")
18 costs = {}
19 costs["a"] = 6
20 costs["b"] = 2
21 costs["fin"] = infinity
22 
23 # the parents table
24 parents = {}
25 parents["a"] = "start"
26 parents["b"] = "start"
27 parents["fin"] = None
28 
29 processed = []
30 
31 def find_lowest_cost_node(costs):
32     lowest_cost = float("inf")
33     lowest_cost_node = None
34     # Go through each node.
35     for node in costs:
36         cost = costs[node]
37         # If it's the lowest cost so far and hasn't been processed yet...
38         if cost < lowest_cost and node not in processed:
39             # ... set it as the new lowest-cost node.
40             lowest_cost = cost
41             lowest_cost_node = node
42     return lowest_cost_node
43 
44 # Find the lowest-cost node that you haven't processed yet.
45 node = find_lowest_cost_node(costs)
46 # If you've processed all the nodes, this while loop is done.
47 while node is not None:
48     cost = costs[node]
49     # Go through all the neighbors of this node.
50     neighbors = graph[node]
51     for n in neighbors.keys():
52         new_cost = cost + neighbors[n]
53         # If it's cheaper to get to this neighbor by going through this node...
54         if costs[n] > new_cost:
55             # ... update the cost for this node.
56             costs[n] = new_cost
57             # This node becomes the new parent for this neighbor.
58             parents[n] = node
59     # Mark the node as processed.
60     processed.append(node)
61     # Find the next node to process, and loop.
62     node = find_lowest_cost_node(costs)
63 
64 print "Cost from the start to each node:"
65 print costs

java代码

//假设起点为src, 终点为dst, 图以二维矩阵的形式存储,若graph[i][j] == 0, 代表i,j不相连    
//visit[i] == 0,代表未访问,visit[0] == -1代表已访问    
public int Dijkstra(int src, int dst, int[][] graph,int[] visit){
    //节点个数        
    int n = graph.length;        
    PriorityQueue<Node> pq = new PriorityQueue<>(new Node());        
    //将起点加入pq        
    pq.add(new Node(src, 0));        
    while (!pq.isEmpty()){            
        Node t = pq.poll();            
        //当前节点是终点,即可返回最短路径            
        if(t.node == dst)                
            return t.cost;            
        //t节点表示还未访问            
        if (visit[t.node]==0){                
            //将节点设置为已访问                
            visit[t.node] = -1;                
            //将当前节点相连且未访问的节点遍历                
            for (int i = 0; i < n; i++) {                    
                if (graph[t.node][i]!=0 && visit[i]==0) {                        
                    pq.add(new Node(i, t.cost + graph[t.node][i]));                    
                }                
            }            
        }        
    }        
    return -1;    
}    
//定义一个存储节点和离起点相应距离的数据结构    
class Node implements Comparator<Node> {        
    public int node;        
    public int cost;
             
    public Node(){}
     
    public Node(int node, int cost){            
        this.node = node;            
        this.cost = cost;        
    }        
    @Override        
    public int compare(Node node1, Node node2){            
        return node1.cost-node2.cost;       
    }    
}

权重

有、无向图

A
B
			                         有向图 
A
B
			                         无向图   							

示例

A
B
C
D
			                         权重:21    							

举例

5
0
15
10
20
20
15
30
乐谱
唱片
海报
吉他
架子鼓
钢琴
父节点节点开销
乐谱唱片 $5
乐谱海报 $0
唱片吉他 $20
唱片架子鼓 $25
吉他钢琴 $40
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值