Dijkstra——最短路径路由算法java实现

         路由算法分为两种:距离矢量算法(DV)和链路状态算法(LS),Dijkstra算法是LS算法的主要表现形式。在路由算法中,Dijkstra算法主体和数据结构与算法课程中的并无二致,只是需要计算源结点到其余所有能够到达结点的路径长度,即把其余所有结点均视为目标结点,并通过表格(数组)对算法过程和结果进行记录。

算法的伪代码如下:

Initialization: 
 N'= {u}
 for all nodes v 
 if v adjacent to u 
 then D(v)= c(u,v)
 else D(v)= ∞
 Loop 
 find w not in N' such that D(w) is a minimum 
/*在集合N'之外找离结点最近的结点w*/
 add w to N'
 update D(v) for all v adjacent to w and not in N': 
 D(v)= min( D(v), D(w)+ c(w,v))
 until all nodes in N'

/*
C (x,y):节点x到y的链路开销;如果不是直接邻居=∞
D(v):从source到dest的路径开销的当前值
P (v):从源到v路径上的前继节点
N’:已知最小代价路径的节点集合
*/

算法的具体java实现如下:

import java.io.IOException;
import java.lang.System;
import java.util.Scanner;

public class Dijkstra {
    public static void main(String[] args) throws IOException {
        int i, j;
        System.out.println("请输入结点总数目:");
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        String[] name = new String[n]; // 储存结点名称5
        int[][] distance = new int[n][n]; // 储存两个点之间的距离,若distance[i][j]为a,则意为从name[i]结点到name[j]结点的距离为a
        System.out.println("请输入各结点名称:");
        for (i = 0; i < n; i++) { // 若a=65536则表示从name[i]到name[j]不连通
            name[i] = scanner.next();
        }
        System.out.println("请输入各结点之间的距离矩阵:");
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                distance[i][j] = scanner.nextInt();
            }
        }
        int[] alreadyIn = new int[n]; // 表示结点是否已被选中过,若是则为1,否则为0
        alreadyIn[0] = 1; // 将源结点置为1,其余结点因为数组为int型自动初始化为0

        int[] minDistance = new int[n]; // 储存源结点到各结点的最短路径
        int min_position = 0;
        // int []index = new int [n];
        int index = 0;
        int[] path = new int[n];
        int[] path_out = new int[n];

        for (i = 1; i < n; i++) {
            minDistance[i] = distance[0][i];
        }
        minDistance[0] = 65536;
        System.out.println("算法过程如下:");
        while (containsAllNodes(alreadyIn, n)) {
            int min = 65535;
            for (i = 1; i < n; i++) {
                if (alreadyIn[i] == 0 && minDistance[i] < min) {
                    min = minDistance[i];
                    index = i;
                }
            }
            alreadyIn[index] = 1;
            for (i = 0; i < n; i++) {
                if (distance[index][i] != 65536 && distance[index][i] != 0 && minDistance[i] > minDistance[index] + distance[index][i]) {
                    minDistance[i] = minDistance[index] + distance[index][i];
                    path[i] = index;
                }
                // minDistance[i] = minDistance[i] < minDistance[index] + distance[index][i] ?
                // minDistance[i] : minDistance[index] + distance[index][i];
            }
            for(i = 1; i < n; i++){
                System.out.print(minDistance[i] + " ");
            }
            System.out.println();

        }

        for (i = 1; i < n; i++) {
            System.out.println("源结点" + name[0] + "到结点" + name[i] + "的最短路径消耗为:" + minDistance[i] + "," + name[i] + "的上一个结点为:" + name[path[i]]);
        }
        scanner.close();
    }

    private static boolean containsAllNodes(int[] alreadyIn, int n) {
        for (int i = 1; i < n; i++) {
            if (alreadyIn[i] == 0)
                return true;
        }
        return false;
    }
}

运行:

Dijkstra——最短路径路由算法java实现_第1张图片

 先输入路由结点的总数目,然后输入名称,最后输入距离矩阵。

该距离矩阵表示的有向图为:

Dijkstra——最短路径路由算法java实现_第2张图片

距离矩阵中[i][j]处为65536表示从i到j不连通,为0表示从i到i自身。(没有两个路由直接的距离为0吧?)

输出:

Dijkstra——最短路径路由算法java实现_第3张图片

该实现结果简要地给出了算法的计算过程:

Dijkstra——最短路径路由算法java实现_第4张图片

并且记录了每一条最短路径目的结点的上一个结点是谁,可以根据这个记录一层一层向上溯源,从而形成一条完整的最短路径。

你可能感兴趣的:(java,算法,网络协议)