zoukankan      html  css  js  c++  java
  • 有向图的单源非负最短路径算法-dijkstra算法

    dijkstra应用范围:O(N2)

    图中各边权值非负。

    最短路径在现实中应用很广,比如在地图上找出最短路径等,这个算法很重要。

    算法思想很简单,它不是找特定节点対之间的最短路径,它是找出源节点到所有其他节点的最短路径。

    怎么找呢?

    所需额外参数:path[] 记录路径。 dist[] 记录路径长度, visited [] 标记已找到最短路径的节点。

    第一步初始化,

    将源节点visited标记为true, 并将其直连边长度,更新到dist[]数组。

    其次要明白所有路径中最短的路径是哪一条?

    肯定是源节点直连边(路径长度为1)中最短的那一条。

    第二条呢?

    必然是直连边或者第一条最短路径再扩一边中的最小边。

    第N条呢?

    如果我们把以求出最短路径的点标记为true,那么可以证明,下一条最短路径必然是true点再扩一条边中的最短边所组成的路径。

    然后我们依次找下去,找N-1次,就可以找到源节点到所有目标节点的最短路径。

    想要找出所有节点间的最短路径,变换源节点,重复N次即可。

    重点在于理解链式路径反应。

    下面给出Java代码,图用邻接矩阵存储:

     1 public int minPath(int source, int target){
     2         if (source == target){
     3             System.out.println("(" + source + " " + target + ")");
     4             return 0;
     5         }
     6         int[] path = dijkstra(source);
     7         int result = 0;
     8         String way = "";
     9         while (-1 != path[target]){
    10             way = "(" + path[target] + " " + target + ") " + way;
    11             result += graph[path[target]][target];
    12             target = path[target];
    13         }
    14         System.out.println(way);
    15         return result;
    16     }
    17     private int[] dijkstra(int vertex){
    18        int[] path = new int[numVertices];
    19        boolean[] visited = new boolean[numVertices];
    20        int[] lenPath = new int[numVertices];
    21 
    22        // initial
    23        int neighbor = getFirstNeighbor(vertex);
    24        while (neighbor != -1){
    25            lenPath[neighbor] = graph[vertex][neighbor];
    26            neighbor = getNextNeighbor(vertex,neighbor);
    27        }
    28        for (int i = 0; i < numVertices; i++) {
    29            if (lenPath[i] == 0){
    30                lenPath[i] = 1000;
    31                path[i] = -1;
    32            }else{
    33                path[i] = vertex;
    34            }
    35        }
    36        visited[vertex] = true;
    37 
    38         // find min pathLen in unvisited vertex.
    39        for (int i = 0; i < numVertices-1; i++) {
    40            int min = vertex;
    41            for (int j = 0; j < numVertices; j++) {
    42                if (visited[j] == false && lenPath[j] < lenPath[min]){
    43                    min = j;
    44                }
    45            }
    46            if (min == vertex){
    47                return path;
    48            }
    49            visited[min] = true;
    50            for (int j = 0; j < numVertices; j++) {
    51                if (visited[j] == false && lenPath[j] > lenPath[min] + graph[min][j]){
    52                    lenPath[j] = lenPath[min] + graph[min][j];
    53                    path[j] = min;
    54                }
    55            }
    56        }
    57        return path;
    58     }
  • 相关阅读:
    局域网中配置多台机器可以登录远程桌面
    集合类接口IEnumerable,IEnumerator,ICollection,IList,IDictionary理解
    C#只允许运行应用程序的一个实例的正确写法
    windows快捷启动命令
    .Net中的Attribute
    NAnt学习笔记(1) NAnt的配置文件结构和一个简单的NAnt例子
    互联网项目管理要点(转)
    .net中的对象序列化(2):三种序列化方式
    NAnt学习笔记(2) 节点的含义解释
    如何在修改checkbox状态,不触发事件
  • 原文地址:https://www.cnblogs.com/zqiguoshang/p/6676479.html
Copyright © 2011-2022 走看看