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

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

时间复杂度为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. asp.net获取文件夹下的所有文件

    using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System. ...

  2. UrlRewriter.dll伪静态实现二级域名泛解析

    大家应该知道,微软的URLRewrite能够对URL进行重写,但是也只能对域名之后的部分进行重写,而不能对域名进行重写, 如:可将 http://http://www.115sou.com/qq/  ...

  3. Java知识点:琐碎知识点(1)

    Java基本介绍 SUN:Stanford University NetworkJava之父:James GoslingJava的跨平台性因为有Java虚拟机,运行class文件.Java吉祥物:Du ...

  4. Android Broadcast Receiver

    说明 有时候我们在做android系统软件的时候,经常会需要做的事就是开机重新设置上次关机前的状态,当然,我们就会用到这个开机广播: <uses-permission android:name= ...

  5. 对于GLM的理解,与方差分析的对比

    最近遇到一个问题,如果因变量为一个连续变量(如胰岛素水平),主要考察的变量为分组变量(如正常血糖组,前糖尿病组,糖尿病组三组),现在的目的是想看调整多种变量(包括多个连续性变量和分类变量)后,胰岛素水 ...

  6. BZOJ3540: [Usaco2014 Open]Fair Photography

    3540: [Usaco2014 Open]Fair Photography Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 72  Solved: 29 ...

  7. db2数据库Date相关函数

    1.db2可以通过SYSIBM.SYSDUMMY1.SYSIBM.DUAL获取寄存器中的值,也可以通过VALUES关键字获取寄存器中的值. SELECT 'HELLO DB2' FROM SYSIBM ...

  8. 【打表】HDOJ-2089-不要62

    [题目链接:HDOJ-2089] 多组测试数据,所以可以先算出符合条件的所有数保存数组中,输入时则直接遍历数组. #include<iostream> #include<cstrin ...

  9. Android UI详解之Fragment加载

    使用Fragment的原因: 1. Activity间的切换不流畅 2. 模块化Activity,方便做局部动画(有时为了到达这一点要把多个布局放到一个activity里面,现在可以用多Fragmen ...

  10. Android Dialog用法

    摘要: 创建对话框 一个对话框一般是一个出现在当前Activity之上的一个小窗口. 处于下面的Activity失去焦点, 对话框接受所有的用户交互. 对话框一般用于提示信息和与当前应用程序直接相关的 ...