(二)Dijkstra算法

一、问题描述

解决最短路径问题。

  • 对于内网图而言(边带权值),最短路径是指两顶点之间经过的边上权值之和最小的路径。
  • 对于非内网图而言(边不带权值),最短路径就是经过的边数和最小的路径。

路径中,第一个顶点为源点,最后一个顶点为终点。所求得是源点到终点的最短路径。

二、Dijkstra算法思想

图可以表示为,G(V, E),V为各个顶点,E为各个顶点所连的边,W为各个边的权值。

记顶点为V0,目标点为Vj,Vk为V0到Vj中间任意一点。

  • 每次遍历开始都可以确定目前与V0连接的最短路径
  • 与V0直连的点未必就是最短路径,除非与V0直连的点距离最短,可以简单证明。
  • 若与V0直连的点Vi不是最短路径,那么其只可能被最短路径更新成更短的路径。D(Vi) = Min(D(Vi), D(VK) + W(VK, Vi)),其中VK为目前的最短路径的顶点。
  • 最短路径已经是不可能再变的了,因为其它路径都比它长,所以不可能以其它路径当成中间点。

因此思想就可以总结出来了:每次都选择最短路径的顶点为中间点,去更新其它顶点上的权值。贪心思想。

三、Code

 1 package algorithm;
 2 
 3 
 4 /**
 5  * Created by adrian.wu on 2019/2/12.
 6  */
 7 public class Dijkstra {
 8     public int dijkstra(int[][] w, int v0, int vj) {
 9         int n = w.length, M = 0x7fffffff;
10         //v0是源点,vj是顶点
11         boolean[] visited = new boolean[n];
12         int[] D = new int[n];
13         for (int i = 0; i < n; i++)
14             D[i] = w[v0][i];
15 
16         for (int i = 0; i < n; i++) {
17             int min = M, k = 0;
18 
19             for (int j = 0; j < n; j++) {
20                 if (min > D[j]) {
21                     min = D[j];
22                     k = j;
23                 }
24             }
25 
26             for (int j = 0; j < n; j++)
27                 D[j] = Math.min(D[j], min + w[k][j]);
28         }
29 
30         return D[vj];
31     }
32 }

猜你喜欢

转载自www.cnblogs.com/ylxn/p/10356898.html