AOE关键路径
这个算法来求关键路径,其实就是利用拓扑排序,首先求出,每个节点最晚开始时间,再倒退求每个最早开始的时间。
从而算出活动最早开始的时间和最晚开始的时间,如果这两个时间相等,则为关键路径。
时间复杂度为O(n+e)
主要算法:
int topSort(Graph *g){
EdgeNode *e;
int i,k,gettop;
int top = ;
int count = ;
int *stack;
stack = (int *)malloc(g->numVertexes * sizeof(int));
for(i=;i<g->numVertexes;i++){
if(g->headlist[i].in == ) //把入度为0的,即没有入度的点入栈
stack[++top] = i;
}
top2 = ;
etv = (int *)malloc(g->numVertexes*sizeof(int));
for(i=;i<g->numVertexes;i++){
etv[i] = ;
}
stack2=(int *)malloc(g->numVertexes*sizeof(int));
while(top){
gettop = stack[top--];
printf("%d ",gettop);
count++;
stack2[++top2] = gettop;
for(e = g->headlist[gettop].fnode; e ; e=e->next){ //一次遍历链表,减少各个子节点的入度
k = e->data;
if(!(--g->headlist[k].in))
stack[++top] = k;
if((etv[gettop]+e->weight)>etv[k]) //选取最大值
etv[k] = etv[gettop]+e->weight;
}
}
if(count < g->numVertexes)
return ERROR;
else
return OK;
}
int critical(Graph *g){
EdgeNode *e;
int i,gettop,k,j;
int ete,lte;
topSort(g);
printf("\n-------------------------------------------\n");
for(i=;i<g->numVertexes;i++){
printf("%d ",etv[i]);
}
printf("\n-------------------------------------------\n");
ltv = (int *)malloc(sizeof(int)*g->numVertexes);
for(i=;i<g->numVertexes;i++){
ltv[i] = etv[g->numVertexes-];
}
while(top2!=){
gettop = stack2[top2--];
for(e = g->headlist[gettop].fnode;e;e = e->next){
k = e->data;
if(ltv[k]-e->weight < ltv[gettop]){
ltv[gettop] = ltv[k] - e->weight;
}
}
}
for(i=;i<g->numVertexes;i++){
printf("%d ",ltv[i]);
}
printf("\n-------------------------------------------\n");
printf("\n");
for(j=;j<g->numVertexes;j++){
for(e=g->headlist[j].fnode; e; e=e->next){
k = e->data;
ete = etv[j];//活动最早
lte = ltv[k] - e->weight;//活动最迟
if(ete == lte)
printf("<v%d v%d>length:%d\n",g->headlist[j].data,g->headlist[k].data,e->weight);
}
}
return ;
}
全部代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 9
#define ERROR 1
#define OK 0
typedef struct edgeNode{
int data;
int weight;
struct edgeNode *next;
}EdgeNode;
typedef struct headNode{
int in;
int data;
EdgeNode *fnode;
}HeadNode,HeadList[MAX];
typedef struct{
HeadList headlist;
int numEdges,numVertexes;
}Graph,*graph; int *etv,*ltv;
int *stack2;
int top2; void initialGraph(Graph *g);
void headinfo(Graph *g,int in,int node);
void linkinfo(Graph *g,int node,int link,int weight);
void printGraph(Graph *g);
int topSort(Graph *g);
int critical(Graph *g); int main(){
Graph *g = (Graph *)malloc(sizeof(Graph));
g->numEdges = ;
g->numVertexes = ;
initialGraph(g);
printGraph(g); critical(g);
//topSort(g); getchar();
return ;
}
int critical(Graph *g){
EdgeNode *e;
int i,gettop,k,j;
int ete,lte; topSort(g);
printf("\n-------------------------------------------\n");
for(i=;i<g->numVertexes;i++){
printf("%d ",etv[i]);
}
printf("\n-------------------------------------------\n");
ltv = (int *)malloc(sizeof(int)*g->numVertexes);
for(i=;i<g->numVertexes;i++){
ltv[i] = etv[g->numVertexes-];
} while(top2!=){
gettop = stack2[top2--];
for(e = g->headlist[gettop].fnode;e;e = e->next){
k = e->data;
if(ltv[k]-e->weight < ltv[gettop]){
ltv[gettop] = ltv[k] - e->weight;
}
}
} for(i=;i<g->numVertexes;i++){
printf("%d ",ltv[i]);
}
printf("\n-------------------------------------------\n");
printf("\n");
for(j=;j<g->numVertexes;j++){
for(e=g->headlist[j].fnode; e; e=e->next){
k = e->data;
ete = etv[j];//活动最早
lte = ltv[k] - e->weight;//活动最迟
if(ete == lte)
printf("<v%d v%d>length:%d\n",g->headlist[j].data,g->headlist[k].data,e->weight);
}
}
return ;
} int topSort(Graph *g){
EdgeNode *e;
int i,k,gettop;
int top = ;
int count = ;
int *stack;
stack = (int *)malloc(g->numVertexes * sizeof(int));
for(i=;i<g->numVertexes;i++){
if(g->headlist[i].in == ) //把入度为0的,即没有入度的点入栈
stack[++top] = i;
} top2 = ;
etv = (int *)malloc(g->numVertexes*sizeof(int));
for(i=;i<g->numVertexes;i++){
etv[i] = ;
}
stack2=(int *)malloc(g->numVertexes*sizeof(int)); while(top){
gettop = stack[top--];
printf("%d ",gettop);
count++;
stack2[++top2] = gettop; for(e = g->headlist[gettop].fnode; e ; e=e->next){ //一次遍历链表,减少各个子节点的入度
k = e->data;
if(!(--g->headlist[k].in))
stack[++top] = k;
if((etv[gettop]+e->weight)>etv[k]) //选取最大值
etv[k] = etv[gettop]+e->weight;
}
}
if(count < g->numVertexes)
return ERROR;
else
return OK;
} void printGraph(graph g){
int i;
printf("vertex:%d,edges:%d\n",g->numVertexes,g->numEdges);
EdgeNode *e = (EdgeNode *)malloc(sizeof(EdgeNode));
for(i=;i<MAX;i++){
printf("[in:%d]%d",g->headlist[i].in,g->headlist[i].data);
e = g->headlist[i].fnode;
while(e != NULL){
printf("->%d(%d)",e->data,e->weight);
e = e->next;
}
printf("\n");
}
free(e);
}
void initialGraph(Graph *g){
headinfo(g,,);
linkinfo(g,,,);
linkinfo(g,,,); headinfo(g,,);
linkinfo(g,,,);
linkinfo(g,,,); headinfo(g,,);
linkinfo(g,,,);
linkinfo(g,,,); headinfo(g,,);
linkinfo(g,,,); headinfo(g,,);
linkinfo(g,,,);
linkinfo(g,,,); headinfo(g,,);
linkinfo(g,,,); headinfo(g,,);
linkinfo(g,,,); headinfo(g,,);
linkinfo(g,,,); headinfo(g,,);
linkinfo(g,,,); headinfo(g,,);
}
void headinfo(Graph *g,int in,int node){
g->headlist[node].in = in;
g->headlist[node].data = node;
g->headlist[node].fnode = NULL;
g->numVertexes++;
}
void linkinfo(Graph *g,int node,int link,int weight){
EdgeNode *en = (EdgeNode *)malloc(sizeof(EdgeNode));
if(g->headlist[node].fnode != NULL){
en->next = g->headlist[node].fnode;
}else{
en->next = NULL;
}
g->headlist[node].fnode = en;
en->data = link;
en->weight = weight;
g->numEdges++;
}
运行示例:

AOE关键路径的更多相关文章
- 2012Hulu校园招聘笔试题
一.填空 侧重逻辑思维,没有语言.具体技术考察,大部分属于组合数学.算法.比较基本的知识点有二元树节点树.最小生成树.Hash函数常用方法等. 二.编程题 1.正整数剖分 2.AOE关键路径 3.二元 ...
- 教你轻松计算AOE网关键路径(转)
原文链接:http://blog.csdn.net/wang379275614/article/details/13990163 本次结合系统分析师-运筹方法-网络规划技术-关键路径章节,对原文链接描 ...
- AOE网上的关键路径(最长路径 + 打印路径)
题目描述 一个无环的有向图称为无环图(Directed Acyclic Graph),简称DAG图. AOE(Activity On Edge)网:顾名思义,用边表示活动的网,当然它也是DAG ...
- 基于AOE网的关键路径的求解
[1]关键路径 在我的经验意识深处,“关键”二字一般都是指临界点. 凡事万物都遵循一个度的问题,那么存在度就会自然有临界点. 关键路径也正是研究这个临界点的问题. 在学习关键路径前,先了解一个AOV网 ...
- 图的关键路径,AOE,完整实现,C++描述
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- 教你轻松计算AOE网关键路径
认识AOE网 有向图中,用顶点表示活动,用有向边表示活动之间开始的先后顺序,则称这种有向图为AOV网络:AOV网络可以反应任务完成的先后顺序(拓扑排序). 在AOV网的边上加上权值表示完成该活动所需的 ...
- AOE网与关键路径简介
前面我们说过的拓扑排序主要是为解决一个工程能否顺序进行的问题,但有时我们还需要解决工程完成需要的最短时间问题.如果我们要对一个流程图获得最短时间,就必须要分析它们的拓扑关系,并且找到当中最关键的流程, ...
- sdut AOE网上的关键路径(spfa+前向星)
http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2498&cid=1304 题目描述 一个无环的有向图称为无环图(Directed Acyc ...
- AOE网络的关键路径问题
关于AOE网络的基本概念可以参考<数据结构>或者search一下就能找到,这里不做赘述. 寻找AOE网络的关键路径目的是:发现该活动网络中能够缩短工程时长的活动,缩短这些活动的时长,就可以 ...
随机推荐
- NSAutoReleasePool
做iPhone应用开发已经2年多了, 但一些基础的概念性问题只是大致了解, 脑袋中有个模糊的概念. 虽然对平时工作开发没什么影响, 不过时间长了, 心里总是有点虚. 所以从现在开始, 每当我遇到一个模 ...
- mysql的MMM高可用方案
1 MMM高可用mysql方案 1.1 方案简介 MMM即Master-Master Replication Manager for MySQL(mysql主主复制管理器)关于mysql主主复 ...
- ORACLE RAC 监听配置 (listener.ora tnsnames.ora)
Oracle RAC 监听器的配置与单实例稍有不同,但原理和实现方法基本上是相同的.在Oracle中 tns进程用于为指定网络地址上的一个或多个Oracle 实例提供服务注册,并响应来自客户端对该服务 ...
- TCP/IP详解学习笔记(14)-TCP连接的未来和性能(未写完)
在TCP刚出世的时候,其主要工作环境是以太网和SLIP之类的低速网络.随着高速网络的出现,让TCP协议的吞吐量更大,效率更高的要求就愈来愈迫切.为此,TCP增加了三个重要机制来对应现在的变化,他们是 ...
- Autofac 依赖注入 ASP.NET MVC5 插件机制中插件的简单实现
一.前言 由于项目业务复杂,创建了多个插件并把他们放在了不同的项目中,项目使用AutoFac做的IOC:但是主项目可以注入,插件注入失败, 没有为该对象定义无参数的构造函数.下面就一步一步注入插件项目 ...
- Domain Name System (DNS)
1.DNS和WINS的作用 DNS:(Domain Name Server,域名服务)用于实现域名和IP地址的相互转换. WINS:(Windows Internet Name Service) 用来 ...
- POJ 1274 The Perfect Stall
题意:有n只牛,m个牛圈(大概是),告诉你每只牛想去哪个牛圈,每个牛只能去一个牛圈,每个牛圈只能装一只牛,问最多能让几只牛有牛圈住. 解法:二分图匹配.匈牙利裸题…… 代码: #include< ...
- POJ 1160 Post Office
题意:有n个村庄,要在其中m个村庄里建邮局,每个村庄去邮局的代价为当前村庄到最近的一个有邮局村庄的路程,问总最小代价是多少. 解法:dp.dp[i][j]表示在前j个村庄建立i个邮局后的代价,则状态转 ...
- Linux Kernel 4.8分支第4个候选版本发布
导读 今天,大神Linus Torvalds宣布了Linux 4.8分支的第四个候选版本,该候选版本在提供常规驱动更新.架构改善和部分KVM调整之外最大的新功能就是修复了英特尔Skylake电源管理B ...
- 对delegate进行扩展 打造通用的"计时完成"方法 z
让用户尽量少打字 每次让用户输入这么多信息的确很糟糕, 可以改进一下设计: 服务器IP和用户名可以存放在配置文件里面, 初始化的时候默认加载到相应的文本框中; 从安全角度考虑, 密码必须经过用户手动输 ...