风也温柔

计算机科学知识库

数据结构关键路径 数据结构C++——关键路径

  数据结构C++——关键路径

  文章目录

  一、前言

  理解关键路径需要掌握拓扑排序和邻接表的相关知识,由于此部分笔者在之前的文章中已经介绍过,此处不再过多赘述,对此部分知识还不熟练的读者,欢迎移步此文章,共同学习!:

  数据结构C++——拓扑排序

  数据结构C++——图的邻接矩阵和邻接表

  二、关键路径的概念

  (1)AOE-网:与AOV-网相对应的是AOE-网 , 即以边表示活动的网。AOE-网是一个带权的有向无环图,其中,顶点表示事件,弧表示活动,权表示活动持续的时间。

  (2)源点和汇点:由于整个工程中只有一个开始点和一个完成点,故在正常的情况(无环)下数据结构关键路径 数据结构C++——关键路径,网中只有一个入度为零的点,称作源点,也只有一个出度为零的点,称作汇点。

  (3)关键路径和关键活动:要估算整项工程完成的最短时间, 就是要找一条从源点到 汇点的带权路径长度最长的路径,称为关键路径。关键路径上的活动叫做关键活动,这些活动是影响工程进度的关键, 它们的提前或拖延将使整个工程提前或拖延。

  三、关键路径的实现 ①关键路径的实现原理

  关键路径算法的实现需要引入两个辅助数组ve[i]和vl[i],分别用来记录事件vi的最早发生时间和记录事件vi的最迟发生时间。遍历整个topo数组,计算出其中存放的顶点(事件)最早发生时间,按逆拓扑序列求出每个事件的最迟发生时间。求出每个边(活动)的最早开始时间和最晚开始时间,边(活动)最早开始时间和最晚开始时间相等的边(活动)即为关键活动。由关键活动形成的由源点到汇点的每一条路径就是关键路径。

  ②关键路径的代码实现

  关键路径的代码实现

   关键路径算法思路:

    1:给每个时间的最早发生时间置初值为0
    2:取得拓扑序列中的顶点,并遍历该顶点的所有邻接点,更新邻接点(事件)发生的最早时间
    3:取得逆拓扑序列中的顶点,遍历该顶点的所有邻接点,更新邻接点(事件)发生的最迟时间
    4:遍历顶点表,输出最早发生时间和最迟发生时间相等的某边(活动)所依附的两个顶点输出

<p><pre>/---------关键路径算法---------/
Status CriticalPath(ALGraph& G) {

//G为邻接表存储的有向图,输出G的各项关键活动
if (!TopologicalSort(G, topo)) return ERROR;
//调用拓扑排序算法,使拓扑序列保存在topo中,若调用失败,则存在有向环,返回ERROR
int n = G.vexnum;//n为顶点个数
for (int i = 0; i weight;
        p = p->nextarc;//p指向k的下一个邻接顶点
    }
}
for (int i = 0; i = 0; i--) {
    int k = topo[i];//取得拓扑序列中的顶点序号k
    ArcNode* p = new ArcNode;
    p = G.vertices[k].firstarc;//p指向k的第一个邻接顶点
    while (p != NULL) {//根据k的邻接点,更新k的最迟发生时间
        int j = p->adjvex;//j为邻接顶点的序号
        if (vl[k] > vl[j] - p->weight)//更新顶点k的最迟发生时间vl[k]
            vl[k] = vl[j] - p->weight;
         p = p->nextarc;//p指向k的下一个邻接顶点
    }
}
/*-----------判断每一个活动是否为关键活动--------------*/
for (int i = 0; i adjvex;//j为邻接顶点的序号
        int e = ve[i];//计算活动的最早开始时间
        int l = vl[j] - p->weight;//计算活动的最迟开始时间
        if (e == l)
            cout  v1 >> v2 >> w;
    int i = LocateVex(G, v1);
    int j = LocateVex(G, v2);
    ArcNode* p1 = new ArcNode;
    p1->adjvex = j;
    p1->weight = w;
    p1->nextarc = G.vertices[i].firstarc;
    G.vertices[i].firstarc = p1;
}

}
void FindInDegree(ALGraph G, int indegree[]) {

for (int i = 0; i nextarc;//指针不断向后指
        }
        indegree[i] = cnt;//将计数结果保留在indegree数组中
    }
}

}
/----------拓扑排序算法---------------/
Status TopologicalSort(ALGraph G, int topo[]) {

//有向图G采用邻接表存储结构
//若G无回路,则生成G的一个拓扑排序topo[]并返回OK,否则ERROR
FindInDegree(G, indegree);//求出各结点的入度存入数组indegree中
SqStack S;
InitStack(S);//初始化栈
for (int i = 0; i adjvex;//vk为vi的邻接点
        --indegree[k];//vi的每个邻接点的入度减一
        if (indegree[k] == 0) Push(S, k);//若入度减为0,则入栈
        p = p->nextarc;//p指向顶点vi下一个邻接结点
    }
}
if (m nextarc;//p指向k的下一个邻接顶点
    }
}
for (int i = 0; i = 0; i--) {
    int k = topo[i];//取得拓扑序列中的顶点序号k
    ArcNode* p = new ArcNode;
    p = G.vertices[k].firstarc;//p指向k的第一个邻接顶点
    while (p != NULL) {//根据k的邻接点,更新k的最迟发生时间
        int j = p->adjvex;//j为邻接顶点的序号
        if (vl[k] > vl[j] - p->weight)//更新顶点k的最迟发生时间vl[k]
            vl[k] = vl[j] - p->weight;
        p = p->nextarc;//p指向k的下一个邻接顶点
    }
}
/*-----------判断每一个活动是否为关键活动--------------*/
for (int i = 0; i adjvex;//j为邻接顶点的序号
        int e = ve[i];//计算活动的最早开始时间
        int l = vl[j] - p->weight;//计算活动的最迟开始时间
        if (e == l)
            cout