迪杰斯特拉算法——dijkstra单源最短路径——贪心求解

文章目录

  • 贪心算法解决dijkstra最短路径问题
        • 1.计算过程
        • 2.代码

贪心算法解决dijkstra最短路径问题

1.计算过程

迪杰斯特拉算法——dijkstra单源最短路径——贪心求解_第1张图片

如图:

初始:定义两个数组:dist[],visit[];一个用来计算距离,一个用来记忆化搜索(搜过的不会再去搜索)。

现在从 V 0 V_0 V0结点出发。初始化 dist[0,inf,inf,inf,inf,inf] (在这里设置0与0结点的距离为0)与 visit[1,0,0,0,0,0](在这里标记0结点已经搜过) 。执行步骤如下:

  • 第一步:

    找到 V 0 V_0 V0相连的边 V 2 , V 4 , V 5 {V_2,V_4,V_5} V2,V4,V5,计算距离:dist[0,inf,10,inf,30,100] 如 果 d i s t [ V 0 ] + 权 值 ( V 0 − V i 的 权 值 ) < d i s t [ V i ] ( i = 2 , 4 , 5 ) , 那 么 就 更 新 d i s t [ V i ] 的 距 离 为 d i s t [ V 0 ] + 权 值 如果dist[V_0]+权值(V_0-V_i的权值)dist[V0]+V0Vi<dist[Vi](i=2,4,5)dist[Vi]dist[V0]+)。

    贪心:找出距离最短所代表的结点(这里索引其实就代表了结点,找的时候从没有标记过结点里面找): V 2 V_2 V2;更新visit[1,0,1,0,0,0],标记 V 2 V_2 V2已经搜过

  • 第二步:

    找到 V 2 V_2 V2相连的边 V 3 V_3 V3,计算距离:dist[0,inf,10,60,30,100] d i s t [ V 2 ] + 权 值 = 60 < d i s t [ V 3 ] = i n f dist[V_2]+权值=60dist[V2]+=60<dist[V3]=inf)。

    贪心:找出距离最短所代表的结点: V 4 V_4 V4;更新visit[1,0,1,0,1,0],标记 V 4 V_4 V4已经搜过。

  • 第三步:

    找出与 V 4 V_4 V4相连的边 V 3 , V 5 V_3,V_5 V3,V5,计算距离:dist[0,inf,10,50,30,90] d i s t [ V 4 ] + 权 值 = 90 < d i s t [ V 5 ] = 100 dist[V_4]+权值=90dist[V4]+=90<dist[V5]=100, d i s t [ V 4 ] + 权 值 = 50 < d i s t [ V 3 ] = 60 dist[V_4]+权值=50dist[V4]+=50<dist[V3]=60)。

    贪心:找出距离最短所代表的结点: V 3 V_3 V3;更新visit[1,0,1,1,1,0],标记 V 3 V_3 V3已经搜过

  • 第四步:

    找出与 V 3 V_3 V3相连的边 V 5 V_5 V5,计算距离:dist[0,inf,10,50,30,60]( d i s t [ V 3 ] + 权 值 = 60 < d i s t [ V 5 ] = 90 dist[V_3]+权值 = 60dist[V3]+=60<dist[V5]=90)

    贪心:找出距离最短所代表的结点: V 3 V_3 V3;更新visit[1,0,1,1,1,1],标记 V 5 V_5 V5已经搜过

  • 计算结束

2.代码


/**
 * 从一个结点出发,找寻最小路径对应的结点
 * 思想:    利用已得到的顶点的最短路径来计算其它顶点的最短路径。
 * 贪心算法:   利用局部最优来计算全局最优。
 *
 *
 */



public class Dij {


    int k= 9;	//结点个数



    //贪心算法体现:找到每一次更新完dist距离数组内的最小值所代表的结点。注意是结点
    int minDist(int[] dist, Boolean[] visit){
        int min = Integer.MAX_VALUE,min_index = -1;

        for (int i = 0; i < k; i++) {
            if ( visit[i] == false && dist[i]<min) {
                min = dist[i];
                min_index = i;
            }
        }
        return min_index;
    }


    int[] dijkstra(int graph[][],int src){
        int dist[] = new int[k];
        Boolean visit[] = new Boolean[k];

        //初始化
        for (int i = 0; i < k; i++) {
            dist[i] = Integer.MAX_VALUE;
            visit[i] = false;
        }

        //设置初始结点距离为0
        dist[src] = 0;


        for (int c = 0; c<k-1;c++){         //遍历k-1次,这样就得到了初始节点结点到所有结点的最短路径

            int u = minDist(dist,visit);      //第一次u是0

            visit[u] = true;          //代表已经搜过

            //在这里对与u结点所有相连的边进行一次距离计算。值得注意的一点是,这里的dis[u]所存储的距离是0结点到u结点的距离
            for (int v = 0; v < k; v++) {
                if (visit[v]==false){             //没有搜过
                    //graph[u][v] !=0 存在边
                    if (graph[u][v] !=0  && dist[u]+graph[u][v]<dist[v]){       //&& dist[u]
                        dist[v] = dist[u]+graph[u][v];
                    }
                }
            }

        }
        return dist;
    }

    public static void main(String[] args) {
        int graph[][] = new int[][]{{0, 4, 0, 0, 0, 0, 0, 8, 0},
                {4, 0, 8, 0, 0, 0, 0, 11, 0},
                {0, 8, 0, 7, 0, 4, 0, 0, 2},
                {0, 0, 7, 0, 9, 14, 0, 0, 0},
                {0, 0, 0, 9, 0, 10, 0, 0, 0},
                {0, 0, 4, 14, 10, 0, 2, 0, 0},
                {0, 0, 0, 0, 0, 2, 0, 1, 6},
                {8, 11, 0, 0, 0, 0, 1, 0, 7},
                {0, 0, 2, 0, 0, 0, 6, 7, 0}};

        Dij t = new Dij();
        int dis[] = t.dijkstra(graph,0);
        for (int i = 0; i < 9; i++) {
            System.out.println(dis[i]);
        }

    }

}

你可能感兴趣的:(Java数据结构,算法,贪心算法,数据结构)