非线性表——图——关键路径/最短路径

9.7.2关键路径

AOE网:

顶点表示事件,弧表示活动,权表示活动持续时间。

把工程计划表示为有向图,

整个工程只有一个开始点(入度为零的点,源点),一个完成点(出度为零的点,汇点)。

路径长度:路径上各活动持续时间(边的权值)之和。

完成工程的最短时间:源点到汇点的最长路径的长度。

关键路径:路径长度最长的路径。

关键活动:关键路径上的活动。

事件vi的最早发生时间ve(i):从源点到顶点vi的最长路径的长度。

求ve(i):从源点开始,按拓扑顺序向汇点递推。

ve(1) =0; ve(i)=Max{ve(k)+dut(<k,i>)|<k,i>∈T,2≤i≤n};

事件vi的最晚发生时间vl(i):在保证汇点按其最早发生时间发生的前提下,求事件vi的最晚发生时间。

求vl(i):从汇点开始,按逆拓扑顺序向源点递推。

vl(n) =ve(n); vl(i)=Min{vl(k)-dut(<i,k>)|<i,k>∈S,1≤i≤n-1};

活动ai的最早开始时间e(i)如果活动ai对应的弧为<j,k>,则e(i)等于从源点到顶点j的最长路径的长度,即e(i)=ve(j)。

活动ai的最晚开始时间l(i):如果活动ai对应的弧为<j,k>,其持续时间为dut(<j,k>),

则l(i)=vl(k)- dut(<j,k>) 。

活动ai的松弛时间(时间余量):l(i)-e(i) 。

松弛时间(时间余量)为0的活动为关键活动。

 

 应用:

 (1)选一条途中中转次数最少的路线 :

从起始点出发对图作广度优先搜索 ,一旦遇到终点停止搜索。

在广度优先搜索生成树上,从起始点到终点的路径就是中转次数最少的路径。

(2)从某顶点出发,沿图的边到达另一顶点所经过的路径中,

各边上权值(交通费用,时间)之和最小的一条路径,即最短路径

9.7.3最短路径

9.7.3.1迪杰斯特拉Dijkstra算法

过程:

引进一辅助向量D,D[i]表示从起始点v0到每个终点vi的已经找到的当前最短路径的长度。

若v0到vi有弧, D[i]的初值为弧上的权值,否则为∞,则D[j]=Min{D[i]|vi∈V}是从v0出发的长度最短的一条最短路径,路径为<v0,vj>。

(1)用带权的邻接矩阵arcs来表示带权有向图;

S为已找到从v0出发的最短路径的终点的集合,初始状态为空集;

辅助向量中D[i]的初值为:D[i]=arcs[v0的位置][i],vi∈V;

(2)选择vj,使D[i]=Min{D[i]|vi∈V-S}, vj即为当前求得的一条从v0出发的最短路径的终点,令S=S∪vj;

(3)修改从v0出发到集合V-S上任一顶点vk可达的最短路径长度,若D[j]+arcs[j][k]<D[k],则将D[k]修改为D[j]+arcs[j][k](vj为中转顶点) 。

(4)重复第2、3步共n-1次。

 

//D[]即为所求,从V0到各个顶点的最短路径
void ShortestPath_DIJ
        ( MGraph G, int v0, PathMatrix p, ShortPathTable D )
{  
   for( v=0; v<G.vexnum; ++v )
     { final[v]=FALSE;     //当为true时,表已求得v0到v的最短路径  
        D[v]=G.arcs[v0][v];  
        for( w=0; w<G.vexnum; ++w )   P[v][w]=FALSE; //p为路径
        if( D[v]<INFINITY )  { p[v][v0]=TRUE; p[v][v]=TRUE; }
     }
  D[v0]=0;                        
  final[v0]=TRUE;         //初始化,表示从V0出发,v0顶点属于S集

//每次求得v0到某顶点v 的最短路径,并加V到S集
for( i=1; i<G.vexnum; ++i )
    { min=INFINITY;
       for( w=0; w<G.vexnum; ++w )   //找最短路径,选顶点V
         if( !final[w] )    if( D[w]<min )  { v=w; min=D[w]; }
       final[v]=TRUE;
       for( w=0; w<G.vexnum; ++w )
         if(!final[w] &&( min+G.arcs[v][w]<D[w] ) )
            { D[w]= min+G.arcs[v][w];  //修改为较小权值
              P[w]=P[v];    //将p[v]行中每个元素赋值给p[w]
              P[w][w]=TRUE;        //表示V0经过v顶点到达w顶点
            }
     }
}

9.7.3.2弗洛伊德(Floyd)算法

算法思想:逐个顶点试探法

求最短路径步骤 :

1、初始时设置一个n阶方阵,令其对角线元素为0。

若存在弧<Vi,Vj>,则对应元素为权值;否则为∞;

2、逐步试着在原直接路径中增加中间顶点,若加入中间点后路径变短,则修改之;

否则,维持原值 。

3、所有顶点试探完毕,算法结束。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值