图-关键路径(AOE网)

  • AOE网:在一个表示工程的带权有向图中,用顶点表示事件,用有向边表示活动,用边上的权值表示活动的持续时间,这种有向图的边表示活动的网,我们称之为AOE网(Activity On Edge Network)。
  • 我们把AOE网中没有入边的顶点称为始点或源点,没有出边的顶点称为终点或汇点。

AOV网与AOE网的比较


名词解释

  • etv(Earliest Time Of Vertex):事件最早发生时间,就是顶点的最早发生时间;
  • ltv(Latest Time Of Vertex):事件最晚发生时间,就是每个顶点对应的事件最晚需要开始的时间,如果超出此时间将会延误整个工期。
  • ete(Earliest Time Of Edge):活动的最早开工时间,就是弧的最早发生时间。
  • lte(Latest Time Of Edge):活动的最晚发生时间,就是不推迟工期的最晚开工时间。


// 边表结点声明
typedef struct EdgeNode
{
    int adjvex;
    struct EdgeNode *next;
}EdgeNode;

// 顶点表结点声明
typedef struct VertexNode
{
    int in;         // 顶点入度
    int data;
    EdgeNode *firstedge;
}VertexNode, AdjList[MAXVEX];

typedef struct
{
    AdjList adjList;
    int numVertexes, numEdges;
}graphAdjList, *GraphAdjList;

int *etv, *ltv;
int *stack2;            // 用于存储拓扑序列的栈
int top2;               // 用于stack2的栈顶指针

// 拓扑排序算法
// 若GL无回路,则输出拓扑排序序列并返回OK,否则返回ERROR
Status TopologicalSort(GraphAdjList GL)
{
    EdgeNode *e;
    int i, k, gettop;
    int top = 0;        // 用于栈指针下标索引
    int count = 0;      // 用于统计输出顶点的个数
    int *stack;         // 用于存储入度为0的顶点
    
    stack = (int *)malloc(GL->numVertexes * sizeof(int));
    
    for( i=0; i < GL->numVertexes; i++ )
    {
        if( 0 == GL->adjList[i].in )
        {
            stack[++top] = i;   // 将度为0的顶点下标入栈
        }
    }
    
    // 初始化etv都为0
    top2 = 0;
    etv = (int *)malloc(GL->numVertexes*sizeof(int));
    for( i=0; i < GL->numVertexes; i++ )
    {
        etv[i] = 0;
    }
    stack2 = (int *)malloc(GL->numVertexes*sizeof(int));
    
    while( 0 != top )
    {
        gettop = stack[top--];      // 出栈
        // printf("%d -> ", GL->adjList[gettop].data); 
        stack2[++top2] = gettop;    // 保存拓扑序列顺序 C1 C2 C3 C4 .... C9
        count++;                
        
        for( e=GL->adjList[gettop].firstedge; e; e=e->next )
        {
            k = e->adjvex;
            // 注意:下边这个if条件是分析整个程序的要点!
            // 将k号顶点邻接点的入度-1,因为他的前驱已经消除
            // 接着判断-1后入度是否为0,如果为0则也入栈
            if( !(--GL->adjList[k].in) )    
            {
                stack[++top] = k;
            }
            
            if( (etv[gettop]+e->weight) > etv[k] )
            {
                etv[k] = etv[gettop] + e->weight;
            }
        }
    }
    
    if( count < GL->numVertexes )   // 如果count小于顶点数,说明存在环
    {
        return ERROR;
    }
    else
    {
        return OK;
    }
}

// 求关键路径,GL为有向图,输出GL的各项关键活动
void CriticalPath(GraphAdjList GL)
{
    EdgeNode *e;
    int i, gettop, k, j;
    int ete, lte;
    
    // 调用改进后的拓扑排序,求出etv和stack2的值
    TopologicalSort(GL);
    
    // 初始化ltv都为汇点的时间
    ltv = (int *)malloc(GL->numVertexes*sizeof(int));
    for( i=0; i < GL->numVertexes; i++ )
    {
        ltv[i] = etv[GL->numVertexes-1];
    }
    
    // 从汇点倒过来逐个计算ltv
    while( 0 != top2 )
    {
        gettop = stack2[top2--];    // 注意,第一个出栈是汇点
        for( e=GL->adjList[gettop].firstedge; e; e=e->next )
        {
            k = e->adjvex;
            if( (ltv[k] - e->weight) < ltv[gettop] )
            {
                ltv[gettop] = ltv[k] - e->weight;
            }
        }
    }
    
    // 通过etv和ltv求ete和lte
    for( j=0; j < GL->numVertexes; j++ )
    {
        for( e=GL->adjList[j].firstedge; e; e=e->next )
        {
            k = e->adjvex;
            ete = etv[j];
            lte = ltv[k] - e->weight;
            
            if( ete == lte )
            {
                printf("<v%d,v%d> length: %d , ", GL->adjList[j].data, GL->adjList[k].data, e->weight );
            }
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 相关概念 AOE网:在一个表示工程的带权有向图中,用顶点表示事件,用有向边表示活动,用边上的权值表示活动的持续时间...
    shawXXQ阅读 2,507评论 0 0
  • 拓扑排序主要是为解决一个工程能否顺序进行的问题, AOV网是 顶点表示活动的网,它只描述活动之间的 制约 关系; ...
    liangxifeng833阅读 720评论 0 1
  • 1 最小生成树(minimum spanning tree) (1)基本概念生成树的概念:一个有 n 个结点的连通...
    1nvad3r阅读 4,048评论 0 5
  • 数据结构学不好,c++就到后面会很迷,数据结构真滴很重要啊,上机题一定要认真做,紧密的和实际操作的代码联系在一起是...
    Nancy_Shi阅读 955评论 0 4
  • 概述 AOE网主要用在如何计算一个工程的完工时间,和优化工程方案减少工程完工时间 在一个表示工程的带权有向图中,用...
    腊鸡程序员阅读 488评论 0 0

友情链接更多精彩内容