数据结构与算法——AOE网的关键路径

数据结构与算法——AOE网的关键路径

在一个表示工程的带权有向图中,用顶点表示事件,用有向边表示活动,用边上的权值表示活动的持续时间,这种有向图的边表示活动的网,称之为AOE网。

AOE网 是建立在子过程之间的制约关系没有矛盾的基础之上,再来分析整个过程需要的开销。所以如果给定AOV网中各顶点活动所需要的时间,则可以转换为AOE网,较为简单的方法就是把每个顶点都拆分成两个顶点,分别表示活动的起点和终点

把上图转换成一般的AOE图如下:

看图分析:

上图为AOE网和AOE转为邻接表结构的存储示意图,其中在边链表中添加weight用于表示活动的权值,数据结构如下;

#include <iostream>
using namespace std;
#define MAXVER 14

typedef struct EdgeNode
{
    int adjvex;
    int weight;
    struct EdgeNode *next;
}EdgeNode;

typedef struct VertexNode 
{
    int in;
    int data;
    EdgeNode* firstedge;
}VertexNode,AdjList[MAXVER];

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

关键路径算法描述

1. 关键路径是AOE网中的最长路径,也是整个工程的最短完成时间;

2. 在关键路径的算法过程中,这两个概念:
     a. 事件(顶点)的最早发生时间:前导事件和活动全部完成时间,就是该事件最早发生的时间;
     b. 事件的最晚发生时间:逆向思考,后一个事件发生的时间,除去该事件需要活动的时间差,为该事件的最迟发生时间;

3. 如果一个事件的最迟发生时间 等于 该事件的最早发生时间,那么弧就是关键活动了,因为它直接决定了这个工程完成的时间

关键路径实现源码

int *etv, *ltv;
int *stack2;
int top2;

bool TopologicalSort(GraphAdjList GL) 
{
    EdgeNode *e;
    int i, k, gettop;
    int top = 0;
    int count = 0;
    int *stack;

    stack = (int*)malloc(GL->numVertexes*sizeof(int));

    for (i = 0; i < GL->numVertexes; i++) 
    {
        if (0 == GL->adjList[i].in) 
        {
            stack[++top] = i;
        }
    }

    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 ( top != 0 ) 
    {
        gettop = stack[top--];
        count++;

        //将弹出的入度为0的顶点放入stack2中
        //有别于stack,这里是遍历的顺序
        stack2[++top2] = gettop;

        for (e = GL->adjList[gettop].firstedge; e; e = e->next) 
        {
            k = e->adjvex;
            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)
        return false;
    else
        return true;

}


void CriticalPath(GraphAdjList GL) 
{
    EdgeNode *e;
    int i, gettop, k, j;
    int ete, lte;
    TopologicalSort(GL);

    ltv = (int*)malloc(GL->numVertexes*sizeof(int));

    for ( i=0;i<GL->numVertexes;i++) 
    {
        ltv[i] = etv[GL->numVertexes - 1];//初始化为最后一个顶点发生的最小时间
    }

    while ( top2 != 0 ) 
    {
        gettop = stack2[top2--];//将拓扑序列出栈,注意这里是按照拓扑排序的逆序

        for (e = GL->adjList[gettop].firstedge;e;e = e->next) 
        {//求各顶点事件的最迟发生时间ltv值
            k = e->adjvex;
            //这里利用尾顶点的最迟发生时间 - 当前弧的权值来得到该顶点的最迟发生时间
            if (ltv[k] - e->weight < ltv[gettop]) 
            {
                ltv[gettop] = ltv[k] - e->weight;
            }
        }

    }


    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)
            {
                cout << "< " << GL->adjList[j].data << "," << GL->adjList[k].data << " > " << endl;
            }

        }

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值