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网络的关键路径目的是:发现该活动网络中能够缩短工程时长的活动,缩短这些活动的时长,就可以 ...
随机推荐
- union与struct以及大小端
两者的区别: 1. 共用体和结构体都是由多个不同的数据类型成员组成, 但在任何同一时刻, 共用体只存放了一个被选中的成员, 而结构体的所有成员都存在. 2. 对于共用体的不同成员赋值, 将会对其它 ...
- linux C 数组操作
/****************************************************************** * linux C 数组操作 * 声明: * 本文为解决陈颖奇遇 ...
- 工作中的 Vim 和 git
————————Vim———————— 1. gf 可以转到文件中指明路径的文件. 这样可以实现文件的快速切换. ctrl+o: A -> B, 返回A ctrl+6: A.B之间快速切换 2 ...
- android的R.java
R.java是个好东西,在Android程序开发过程中为你统一管理资源,添加ID,不可谓不犀利.不过有的时候好东西就越是娇贵,在写Android代码的时候,R.java频繁出错,搞得我是身心俱疲.数次 ...
- HDU 5114 Collision
Collision Time Limit: 15000/15000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others) Total ...
- firebug console使用
Firebug内置一个console对象,提供5种方法,用来显示信息. console.log("Hello World") console.info("这是info&q ...
- VS2010生成Qt程序图标修改方法
转自:http://blog.csdn.net/simeone18/article/details/7344547 1.准备ico文件,nuistcard.ico 2.在nuistcard工程目录,建 ...
- .NET开发工具
1.Two monitors 2.Visual Studio 3.TestDriven.NET 4.JetBrains ReSharper 5.VS样式 https://studiostyl.es/
- Asp.Net中文本换行
Asp.Net中文本换行 VB.NET Function HtmlCode(ByVal fString) If fString <> "" Then ...
- js控制不同的时间段显示不同的css样式
js控制不同的时间段显示不同的css样式 js函数,可以放到单独的js文件中也可以放到当前页的<head>标记之内 function getCSS(){ datetoday ...