这个算法来求关键路径,其实就是利用拓扑排序,首先求出,每个节点最晚开始时间,再倒退求每个最早开始的时间。

从而算出活动最早开始的时间和最晚开始的时间,如果这两个时间相等,则为关键路径。

时间复杂度为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关键路径的更多相关文章

  1. 2012Hulu校园招聘笔试题

    一.填空 侧重逻辑思维,没有语言.具体技术考察,大部分属于组合数学.算法.比较基本的知识点有二元树节点树.最小生成树.Hash函数常用方法等. 二.编程题 1.正整数剖分 2.AOE关键路径 3.二元 ...

  2. 教你轻松计算AOE网关键路径(转)

    原文链接:http://blog.csdn.net/wang379275614/article/details/13990163 本次结合系统分析师-运筹方法-网络规划技术-关键路径章节,对原文链接描 ...

  3. AOE网上的关键路径(最长路径 + 打印路径)

    题目描述 一个无环的有向图称为无环图(Directed Acyclic Graph),简称DAG图.     AOE(Activity On Edge)网:顾名思义,用边表示活动的网,当然它也是DAG ...

  4. 基于AOE网的关键路径的求解

    [1]关键路径 在我的经验意识深处,“关键”二字一般都是指临界点. 凡事万物都遵循一个度的问题,那么存在度就会自然有临界点. 关键路径也正是研究这个临界点的问题. 在学习关键路径前,先了解一个AOV网 ...

  5. 图的关键路径,AOE,完整实现,C++描述

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  6. 教你轻松计算AOE网关键路径

    认识AOE网 有向图中,用顶点表示活动,用有向边表示活动之间开始的先后顺序,则称这种有向图为AOV网络:AOV网络可以反应任务完成的先后顺序(拓扑排序). 在AOV网的边上加上权值表示完成该活动所需的 ...

  7. AOE网与关键路径简介

    前面我们说过的拓扑排序主要是为解决一个工程能否顺序进行的问题,但有时我们还需要解决工程完成需要的最短时间问题.如果我们要对一个流程图获得最短时间,就必须要分析它们的拓扑关系,并且找到当中最关键的流程, ...

  8. sdut AOE网上的关键路径(spfa+前向星)

    http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2498&cid=1304 题目描述 一个无环的有向图称为无环图(Directed Acyc ...

  9. AOE网络的关键路径问题

    关于AOE网络的基本概念可以参考<数据结构>或者search一下就能找到,这里不做赘述. 寻找AOE网络的关键路径目的是:发现该活动网络中能够缩短工程时长的活动,缩短这些活动的时长,就可以 ...

随机推荐

  1. UVa 120 Stacks of Flapjacks【构造法】

    题意:给出n张煎饼,从上到下输入,每张煎饼上面都有一个数字,厨师每次可以选择第k张煎饼,进行翻转操作,设计一种方法使得所有煎饼按照从小到大排序(最上面的煎饼最小) 首先是这个翻转的操作,如下图 如图所 ...

  2. Java Web编程的主要组件技术——JDBC

    参考书籍:<J2EE开源编程精要15讲> JDBC(Java DataBase Connectivity)是Java Web应用程序开发的最主要API之一.当向数据库查询数据时,Java应 ...

  3. jQuery实战读书笔记(备忘录)

    选择器备忘: | :even 匹配所有索引值为偶数的元素,从 0 开始计数 :odd 匹配所有索引值为奇数的元素,从 0 开始计数 实例——设置table交替行变色: <script type= ...

  4. <十>面向对象分析之UML核心元素之关系

    关系        --->在UML中关系是非常重要的语义,它抽象出对象之间的联系,让对象构成特定的结构.        一,关联关系(association)

  5. Android01--开发环境搭建

    1 -- 下载所需软件 Android SDK下载地址:http://developer.android.com/sdk/index.html Eclipse下载地址:http://www.eclip ...

  6. 【转】匹配dll(exe)和pdb方法

    1. 静态检查windbg 调试工具包中有一个工具symchk.exe, 选项很多, 下面一个简单的用法可以检查一个 test.exe能不能找到与它匹配的PDB: 这是成功的情形. 下面来个失败的作为 ...

  7. Vijos 1132 求二叉树的先序序列

    描述 给出一棵二叉树的中序与后序排列.求出它的先序排列.(约定树结点用不同的大写字母表示,长度≤8). 格式 输入格式 第一行为二叉树的中序序列 第二行为二叉树的后序序列 输出格式 一行,为二叉树的先 ...

  8. Permutations java实现

    Given a collection of numbers, return all possible permutations. For example,[1,2,3] have the follow ...

  9. excel 经验总结

    1.2007版excel表格中怎么将使用字母+数字下拉排序 比如:A201110300001怎么在excel表格中往下拉的时候变成A201110300002.A201110300003…… 方法: 因 ...

  10. JDBC第一天连接池案例

    JDBC,JDBC的工具类JDBC 连接从连接池中拿: 创建连接池的语句: package day01; import java.sql.Connection; import java.sql.Dri ...