关键路径的实现
来源:互联网 发布:pyqt5 知乎问答 编辑:程序博客网 时间:2024/03/29 09:05
在介绍关键路径之前,先介绍一个拓扑排序。其实这个概念我并不是很理解,通俗的讲就是由一个节点出发,会一直走到后面的节点,不会返回到已经访问过的节点,如何判断一个图是否是拓扑排序。(1)在有向图中选一个没有前驱的顶点输出,(2)从图中删除该顶点和所有以它为尾的弧。直至图中没有节点或没有入度为0的点。
在此基础上,引入关键路径,在拓扑排序的基础上加上边的权值,完成一个工程从开始点到完成点的最长路径的长度。路径长度最长的路径叫做关键路径,关键路径上的所有活动都是关键活动。关键活动就是要找e(i)==l(i),时间最早发生时间ve,时间最晚发生时间vl。这个概念我也很难解释,挺难说清楚的,自己多看看例子吧。如何求解ve和vl呢。ve(0)=0开始向前递推ve(j) = max{ve(i)+dut(i,j)};求出ve后,vl(n-1) = ve(n-1);向后递推,vl(i) = Min{vl(j) - dut(i,j)};
#include "graph.h"
#include <stdio.h>
#include <queue>
#include <stack>
using namespace std;
//#define DEBUG
stack<int> s; //保存拓扑逆序
int ve[MAX_VERTEX_NUM]; //记录最早时间
int vl[MAX_VERTEX_NUM]; //记录最晚时间
/*********************************************/
/* 拓扑排序 */
/* 参数:G */
/* 功能 检查图中是否有环 */
/*********************************************/
void TopologicalSort(const MGraph *g)
{
int indegree[MAX_VERTEX_NUM]; //入度
int i,j;
for(i=0;i<g->vexnum;i++)
{
indegree[i] = 0;
ve[i] = 0;
}
//初始化节点的入度
for(i=0;i<g->vexnum;i++)
for(j=0;j<g->vexnum;j++)
{
if(g->arcs[i][j]!=INT_MAX)
{
indegree[j]++;
}
}
int count=0; //输出节点的个数
queue<int> q; //存放入度为0的点
for(i=0;i<g->vexnum;i++)
{
if(!indegree[i])
{
q.push(i);
indegree[i]--; //表明已入过队列
}
}
//依次输出入度为0的点
//没输出一个点将相连点的入度减1
//再将入度为0的点入队列
while(!q.empty())
{
int temp;
temp = q.front();
s.push(temp); //依次逆序进栈
// printf("%d",g->vexs[i]);
count++;
for(i=0;i<g->vexnum;i++)
{
if(g->arcs[temp][i]!=INT_MAX)
{
indegree[i]--; //删除节点,相邻节点入度减1
if((ve[temp]+g->arcs[temp][i])>ve[i])
{
ve[i] = ve[temp]+g->arcs[temp][i]; //修改最早时间
}
}
}
q.pop();
for(i=0;i<g->vexnum;i++)
{
if(!indegree[i])
{
q.push(i);
indegree[i]--;
}
}
}
if(count != g->vexnum)
printf("There is a ring!\n");
else
{
// printf("拓扑排序完成!\n");
#ifdef DEBUG
for(i=0;i<g->vexnum;i++)
printf("%d ",ve[i]);
printf("\n");
#endif
}
}
//在求最迟发生时间时,我直接拷贝求最早发生时间的做法
//由出度开始升入
void CriticalPath(const MGraph *g)
{
// int outdegree[MAX_VERTEX_NUM]; //出度
int i,j;
for(i=0;i<g->vexnum;i++)
{
// outdegree[i] = 0;
vl[i] = INT_MAX; //在这赋最大值,求的是最小值
}
/* for(i=0;i<g->vexnum;i++)
for(j=0;j<g->vexnum;j++)
{
if(g->arcs[i][j].adj!=INT_MAX)
{
outdegree[i]++;
}
}
*/
int count; //输出节点的个数
count = s.top();
vl[count] = ve[count];
count = 0;
// queue<int> q; //存放入度为0的点
/* for(i=0;i<g->vexnum;i++)
{
if(!outdegree[i])
{
q.push(i);
vl[i] = ve[i]; //汇点赋值
}
}
*/ //依次输出入度为0的点
//没输出一个点将相连点的入度减1
//再将入度为0的点入队列
while(!s.empty())
{
int temp;
temp = s.top();
// printf("%d",g->vexs[i]);
count++;
for(i=0;i<g->vexnum;i++)
{
if(g->arcs[i][temp]!=INT_MAX) //以将删节点为尾的弧
if((vl[temp] - g->arcs[i][temp]) < vl[i])
{
vl[i] = vl[temp]-g->arcs[i][temp];
}
}
s.pop();
/* for(i=0;i<g->vexnum;i++)
{
if(!indegree[i])
q.push(i);
}
*/ }
//求得最迟时间后,可以与最早时间比较。得关键路径。。
if(count != g->vexnum)
printf("There is a ring!\n");
else
{
printf("关键路径:");
#ifdef DEBUG
for(i=0;i<g->vexnum;i++)
printf("%d ",vl[i]);
#endif
}
for(i=0;i<g->vexnum;i++)
if(vl[i] == ve[i])
printf("%d ",g->vexs[i]);
}
/*test
9 11
1 2 3 4 5 6 7 8 9END
1 2 6
1 3 4
1 4 5
2 5 1
3 5 1
4 6 2
5 7 9
5 8 7
6 8 4
7 9 2
8 9 4
end*/
- 关键路径的实现
- 关键路径的实现 C++代码实现
- 图的关键路径的实现
- 关键路径的实现C++ 代码
- C语言实现“关键路径”的求解
- 关键路径实现
- 关键路径算法实现
- 关键路径 代码实现
- 关键路径C++实现
- 关键路径的选取
- 图的关键路径
- 图的关键路径
- 图的关键路径
- 图的关键路径
- 关键路径的计算
- 图的关键路径
- 图的关键路径
- 图的关键路径
- 请问用ADO连接远程数据库的连接字符串是什么(转载)
- 20120502学习总结
- unity3d简单的音乐播放器
- 关于UNIX和Linux系统下SUID、SGID的解析
- vimtutor
- 关键路径的实现
- Android Listener侦听的N种写法
- linux shell使用经验
- Android动画开发——Animation动画效果
- 生命的答案水知道(只有部分图片,要全的图片自己还是的网上下个pdf看吧)
- hash算法--one-way hash
- PHP数据类型总结
- 10000000000000000不是整数,以及 10000000000000000 === 9999999999999999
- Android 滑动效果入门篇(一)—— ViewFlipper