载入中...
 
     
 
载入中...
时 间 记 忆
载入中...
最 新 评 论
载入中...
专 题 分 类
载入中...
最 新 日 志
载入中...
最 新 留 言
载入中...
搜 索
用 户 登 录
载入中...
友 情 连 接
博 客 信 息
载入中...


 
 
载入中...
   
 
 
关键路径算法
[ 2008-9-16 19:59:00 | By: wantnon ]
 
一,AOE网:(待)
二,最早开始时间与关键路径:
由于求关键路径必须在拓扑有序的前提下进行,所以可以拓扑排序算法为基础,这样,对于不合要求的(非AOE)网络同时给出检测。
算法1:
1,求G中各顶点入度;
   入度为0者加入S;
   如果S为空,有环,退出。
2,从S中任取一点v输出到S';
   更新各顶点入度;
   入度为0者加入S;
   用v冲洗其各直接后继的累积值(Max);
   如果S为空且G-S-S'不为空,有环,退出;
   如果S为空且G-S-S'为空,排序完毕,终止;
   返回2;
结果:最后一个加入S的顶点的累积时间就是最早完工时间。
注:
1,S保持其中顶点累积值已达终态。
原因是:算法中S中顶点在输出时要冲洗其直接后继,又由拓扑排序算法知S保持其中顶点前驱均已输出,故S中顶点已被其所有直接前驱冲过,故累积值已达终态。
2,另设一数组追踪路径即可。
三,最迟开始时间与时间余量:
(待)
--
附:
算法1的C++程序:
#i nclude<iostream.h>
CritPath(double weivvmat[][MAXNL+1],int Nv)
{   
    int i,j;
    int S_[MAXNL+1]={0};//保存已摘掉的顶点(终止时为所求结果)
    int nS_=0;//S_的大小
    int S[MAXNL+1]={0};//保存未摘掉的顶点中入度为0者
    int nS=0;//S的大小
    int indeg[MAXNL+1]={0};//各点剩余入度
    int sumT[MAXNL+1]={0};//各点累积时间
    int foev[MAXNL+1]={0};//各点的前驱
    //初始化indeg
    for(i=1;i<=Nv;i++)//搜各顶点
    {//求顶点i的入度
        int sum=0;
        for(j=1;j<=Nv;j++)//搜点i的邻接点
            if(weivvmat[j][i]!=INF)sum++;
        indeg[i]=sum;//得到顶点i的入度
        if(indeg[i]==0)//如果入度为0,则加入到S
            S[++nS]=i;
    }//indeg初始完毕
    if(nS==0)//如果S为空,说明根本不存在源
    {
        cout<<"错误:有环! 1"<<endl;
        exit(1);
    }
    //循环
    while(1)
    {   /*对于当前S中任一顶点,其所有前驱必定均已输出,
        即此顶点已被其所有直接前驱冲过,
        故S中任一顶点的累积量已经是最态值*/
        int ver=S[nS--];
        S_[++nS_]=ver;
        //更新indeg和sumT和foev
        for(i=1;i<=Nv;i++)//搜ver的邻接点
        {
            if(weivvmat[ver][i]!=INF)
            {//如果i是ver的邻接点
                indeg[i]--;//更新i的入度
                if(indeg[i]==0)//如果i的入度为0,则加进S
                    S[++nS]=i;
                //更新i的累积时间和前驱
                if(sumT[ver]+weivvmat[ver][i]>sumT[i])
                {
                    sumT[i]=sumT[ver]+weivvmat[ver][i];
                    foev[i]=ver;
                }
            }
        }
        if(nS==0)
        {
            if(Nv-nS-nS_==0)
            {
                break;
            }else
            {
                cout<<"错误:有环! 2"<<endl;
                exit(1);
            }
        }
    }
    //输出关键路径
    int p=S_[nS_];
    while(p!=0)
    {
        cout<<p<<"("<<sumT[p]<<")"<<"←";
        p=foev[p];
    }
    cout<<endl;
}
 
 
发表评论:
载入中...
 
     
   
     
Powered by Oblog.