图-最短路径问题

  从某个源点到其余各顶点的最短路径

迪杰斯特拉(Dijkstra)算法

迪杰斯特拉算法是一个按路径长度递增的次序产生最短路径的算法。(负值圈该算法无效)

算法描述:

  1. 假设用带权的邻接矩阵 arcs表示带权有向图,arcs[i][j]表示弧<vi,vj>上的权值;若<vi,vj>不存在,则arcs[i][j]为∞,S为已找到的从v0顶点出发的最短路径的终点的集合,初始状态为空.
  2. 选择 v0到 V-S中顶点构成的最短路径<v0,vj>,并将vj加入S。
  3. 由于vj加入到S中,最短路径发生变化,修改v0到V-S可能的最短路径
  4. 重复第2、3步n-1次,得到从v0到图上其余顶点的最短路径是依次递增的序列

该算法最终的得到的是一个递增的最短路径序列,每次循环中是先找到剩余路径中的最短的一条,再更新一下剩余的最短路径,好像一个选择排序一样,每次选择后面的最小的一个放到前面,最终的到一个有序序列,该序列就是从源点到图中各个顶点的最短路径。

/*
    G.arcs  : 带权邻接矩阵
    vo : 源点
    P  : 存储路径的矩阵
    D  : 存储 v0到 vi的最短路径长度 
*/
void shortestPath_DLJ(MGraph G, int v0, PathMatrix &P, ShortPathTable &D) {
    /*
        求从 v0顶点到其余顶点 v的最短路径P[v]及带权长度D[v]
        P[v][w]为true表示 w是从 v0到 v当前求得最短路径上的顶点
        
        final[v]为true表示已经求得从 v0到 v的最短路径 ,
        即将顶点 v加入到 S集中 
    */ 
    //初始化 
    for(v = 0; v < G.vexnum; v++){
        final[v] = false;
        
        //若 v0到 v有弧,则赋给D[v]的为其权值,否则为INFINITY
        //G.arcs中两顶点无弧,其值已为INFINITY 
        D[v] = G.arcs[v0][v];
        
        //置空路径 
        for(w = 0; w < G.vexnum; w++) P[v][w] = flase;
        
        //若D[v]值小于INFINTY,说明 v0到 v有弧,v0, v自然在路径上
        if(D[v] < INFINTY){ P[v][v0] = true; P[v][v] = true;} 
    }
    
    // 初始化,v0属于 S集 
    D[v0] = 0; final[v0] = true;
    
    //开始主循环,每次求得 v0到 v顶点的最短路径,将 v加入到 S集
    //其余 G.vexnum - 1个顶点 
    for(i = 1; i < G.vexnum; i++){
        //当前离 v0最短距离 
        min = INFINTY;
        
        for(w = 0; w < G.vexnum; w++) 
            //顶点在 V-S中 
            if(!final[v]){ v = w; min = D[w];}
        
        //找到了,将 v加入到 S集 
        final[v] = true;
        
        /*    更新最短路径及距离
            因 v加入到 S集,产生了有 v顶点的新路径
            重新判断最短路径,用于下次找最短路径 
        */ 
        for(w = 0; w < G.vexnum; w++)
            if(!final[w] && min + G.arcs[v][w] < D[w]){
                D[w] = min + G.arcs[v][w];
                //将 v0到 v的路径 P[v]赋给 P[w] 
                //w也在该路径上
                P[w] = P[v];
                P[w][w] = true; 
            } 
    }    
}

待续。。。

猜你喜欢

转载自www.cnblogs.com/haiyuexiaozu/p/11634853.html