_DataStructure_C_Impl:AOE网的关键路径
//_DataStructure_C_Impl:CriticalPath
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"SeqStack.h"
//图的邻接表类型定义
typedef char VertexType[4];
typedef int InfoPtr; //定义为整型,为了存放权值
typedef int VRType; #define MaxSize 50 //最大顶点个数
typedef enum{DG,DN,UG,UN}GraphKind; //图的类型:有向图、有向网、无向图和无向网
//边结点的类型定义
typedef struct ArcNode{
int adjvex; //邻接点域,弧指向的顶点的位置
InfoPtr *info; //弧的权值
struct ArcNode *nextarc; //指示下一个与该顶点相邻接的顶点
}ArcNode;
//头结点的类型定义
typedef struct VNode{
VertexType data; //用于存储顶点
ArcNode *firstarc; //指示第一个与该顶点邻接的顶点
}VNode,AdjList[MaxSize];
//图的类型定义
typedef struct{
AdjList vertex;
int vexnum,arcnum; //图的顶点数目与弧的数目
GraphKind kind; //图的类型
}AdjGraph;
//返回图中顶点相应的位置
int LocateVertex(AdjGraph G,VertexType v){
int i;
for(i=0;i<G.vexnum;i++)
if(strcmp(G.vertex[i].data,v)==0)
return i;
return -1;
}
//採用邻接表存储结构,创建有向网N
void CreateGraph(AdjGraph *N){
int i,j,k,w;
VertexType v1,v2; //定义两个顶点v1和v2
ArcNode *p;
printf("请输入图的顶点数,边数(逗号分隔): ");
scanf("%d,%d",&(*N).vexnum,&(*N).arcnum);
printf("请输入%d个顶点的值:\n",N->vexnum);
for(i=0;i<N->vexnum;i++){
scanf("%s",N->vertex[i].data);
N->vertex[i].firstarc=NULL; //将相关联的顶点置为空
}
printf("请输入弧尾和弧头(以空格作为间隔):\n");
for(k=0;k<N->arcnum;k++){ //建立边链表
scanf("%s%s%*c%d",v1,v2,&w);
i=LocateVertex(*N,v1);
j=LocateVertex(*N,v2);
//j为弧头i为弧尾创建邻接表
p=(ArcNode *)malloc(sizeof(ArcNode));
p->adjvex=j;
p->info=(InfoPtr*)malloc(sizeof(InfoPtr));
*(p->info)=w;
//将p指向的结点插入到边表中
p->nextarc=N->vertex[i].firstarc;
N->vertex[i].firstarc=p;
}
(*N).kind=DN;
}
//销毁无向图G
void DestroyGraph(AdjGraph *G){
int i;
ArcNode *p,*q;
for(i=0;i<(*G).vexnum;++i){ //释放图中的边表结点
p=G->vertex[i].firstarc; //p指向边表的第一个结点
if(p!=NULL){ //假设边表不为空,则释放边表的结点
q=p->nextarc;
free(p);
p=q;
}
}
(*G).vexnum=0; //将顶点数置为0
(*G).arcnum=0; //将边的数目置为0
}
//输出图的邻接表
void DisplayGraph(AdjGraph G){
int i;
ArcNode *p;
printf("%d个顶点:\n",G.vexnum);
for(i=0;i<G.vexnum;i++)
printf("%s ",G.vertex[i].data);
printf("\n%d条边:\n",G.arcnum);
for(i=0;i<G.vexnum;i++)
{
p=G.vertex[i].firstarc;
while(p)
{
printf("<%s,%s,%d> ",G.vertex[i].data,G.vertex[p->adjvex].data,*(p->info));
p=p->nextarc;
}
printf("\n");
}
}
//*********************************************************
int ve[MaxSize]; //ve存放事件最早发生时间
/*採用邻接表存储结构的有向网N的拓扑排序,并求各顶点相应事件的最早发生时间ve*/
/*假设N无回路。则用用栈T返回N的一个拓扑序列,并返回1,否则为0*/
int TopologicalOrder(AdjGraph N,SeqStack *T){
int i,k,count=0;
int indegree[MaxSize]; //数组indegree存储各顶点的入度
SeqStack S;
ArcNode *p;
//将图中各顶点的入度保存在数组indegree中
for(i=0;i<N.vexnum;i++) //将数组indegree赋初值
indegree[i]=0;
for(i=0;i<N.vexnum;i++){
p=N.vertex[i].firstarc;
while(p!=NULL){
k=p->adjvex;
indegree[k]++;
p=p->nextarc;
}
}
//初始化栈S
InitStack(&S);
printf("拓扑序列:");
for(i=0;i<N.vexnum;i++)
if(!indegree[i]) //将入度为零的顶点入栈
PushStack(&S,i);
InitStack(T); //初始化逆拓扑排序顶点栈
for(i=0;i<N.vexnum;i++) //初始化ve
ve[i]=0;
while(!StackEmpty(S)){ //假设栈S不为空
PopStack(&S,&i); //从栈S将已拓扑排序的顶点i弹出
printf("%s ",N.vertex[i].data);
PushStack(T,i); //i号顶点入逆拓扑排序栈T
count++; //对入栈T的顶点计数
for(p=N.vertex[i].firstarc;p;p=p->nextarc){ //处理编号为i的顶点的每一个邻接点
k=p->adjvex; //顶点序号为k
if(--indegree[k]==0) //假设k的入度减1后变为0,则将k入栈S
PushStack(&S,k);
if(ve[i]+*(p->info)>ve[k]) //计算顶点k相应的事件的最早发生时间
ve[k]=ve[i]+*(p->info);
}
}
if(count<N.vexnum){
printf("该有向网有回路\n");
return 0;
}else
return 1;
}
//输出AOE网N的关键路径
int CriticalPath(AdjGraph N){
int vl[MaxSize]; //事件最晚发生时间
SeqStack T;
int i,j,k,e,l,dut,value,count,e1[MaxSize],e2[MaxSize];
ArcNode *p;
if(!TopologicalOrder(N,&T)) //假设有环存在,则返回0
return 0;
value=ve[0];
for(i=1;i<N.vexnum;i++)
if(ve[i]>value)
value=ve[i]; //value为事件的最早发生时间的最大值
for(i=0;i<N.vexnum;i++) //将顶点事件的最晚发生时间初始化
vl[i]=value;
while(!StackEmpty(T)) //按逆拓扑排序求各顶点的vl值
for(PopStack(&T,&j),p=N.vertex[j].firstarc;p;p=p->nextarc){ //弹出栈T的元素,赋给j,p指向j的后继事件k
k=p->adjvex;
dut=*(p->info); //dut为弧<j,k>的权值
if(vl[k]-dut<vl[j])//计算事件j的最迟发生时间
vl[j]=vl[k]-dut;
}
printf("\n事件的最早发生时间和最晚发生时间\ni ve[i] vl[i]\n");
for(i=0;i<N.vexnum;i++) //输出顶点相应的事件的最早发生时间最晚发生时间
printf("%d %d %d\n",i,ve[i],vl[i]);
printf("关键路径为:(");
for(i=0;i<N.vexnum;i++) //输出关键路径经过的顶点
if(ve[i]==vl[i])
printf("%s ",N.vertex[i].data);
printf(")\n");
count=0;
printf("活动最早開始时间和最晚開始时间\n 弧 e l l-e\n");
for(j=0;j<N.vexnum;j++)
for(p=N.vertex[j].firstarc;p;p=p->nextarc){
k=p->adjvex;
dut=*(p->info); //dut为弧<j,k>的权值
e=ve[j]; //e就是活动<j,k>的最早開始时间
l=vl[k]-dut; //l就是活动<j,k>的最晚開始时间
printf("%s→%s %3d %3d %3d\n",N.vertex[j].data,N.vertex[k].data,e,l,l-e);
if(e==l){ //将关键活动保存在数组中
e1[count]=j;
e2[count]=k;
count++;
}
}
printf("关键活动为:");
for(k=0;k<count;k++) //输出关键路径
{
i=e1[k];
j=e2[k];
printf("(%s→%s) ",N.vertex[i].data,N.vertex[j].data);
}
printf("\n");
return 1;
}
void main(){
AdjGraph N;
CreateGraph(&N); /*採用邻接表存储结构创建有向网N*/
DisplayGraph(N); /*输出有向网N*/
CriticalPath(N); /*求网N的关键路径*/
DestroyGraph(&N); /*销毁网N*/
system("pause");
}
#pragma once
#include<stdio.h>
#include<stdlib.h>
#define StackSize 100
typedef int DataType; //栈元素类型定义
typedef struct{
DataType stack[StackSize];
int top;
}SeqStack;
//将栈初始化为空栈仅仅须要把栈顶指针top置为
void InitStack(SeqStack *S){
S->top=0;//把栈顶指针置为0
}
//推断栈是否为空。栈为空返回1,否则返回0
int StackEmpty(SeqStack S){
if(S.top==0)
return 1;
else
return 0;
}
//取栈顶元素。将栈顶元素值返回给e,并返回1表示成功;否则返回0表示失败。
int GetTop(SeqStack S,DataType *e){
if(S.top<=0){ //在取栈顶元素之前。推断栈是否为空
printf("栈已经空!\n");
return 0;
}else{
*e=S.stack[S.top-1]; //在取栈顶元素
return 1;
}
}
//将元素e进栈。元素进栈成功返回1,否则返回0
int PushStack(SeqStack *S,DataType e){
if(S->top>=StackSize){ //在元素进栈前,推断是否栈已经满
printf("栈已满。不能进栈! \n");
return 0;
}else{
S->stack[S->top]=e; //元素e进栈
S->top++; //改动栈顶指针
return 1;
}
}
//出栈操作。将栈顶元素出栈。并将其赋值给e。出栈成功返回1。否则返回0
int PopStack(SeqStack *S,DataType *e){
if(S->top<=0){ //元素出栈之前,推断栈是否为空
printf("栈已经没有元素,不能出栈!\n");
return 0;
}else{
S->top--; //先改动栈顶指针。即出栈
*e=S->stack[S->top]; //将出栈元素赋值给e
return 1;
}
}
//求栈的长度。即栈中元素个数,栈顶指针的值就等于栈中元素的个数
int StackLength(SeqStack S){
return S.top;
}
//清空栈的操作
void ClearStack(SeqStack *S){
S->top=0;
}
_DataStructure_C_Impl:AOE网的关键路径的更多相关文章
- AOE网与关键路径简介
前面我们说过的拓扑排序主要是为解决一个工程能否顺序进行的问题,但有时我们还需要解决工程完成需要的最短时间问题.如果我们要对一个流程图获得最短时间,就必须要分析它们的拓扑关系,并且找到当中最关键的流程, ...
- 基于AOE网的关键路径的求解
[1]关键路径 在我的经验意识深处,“关键”二字一般都是指临界点. 凡事万物都遵循一个度的问题,那么存在度就会自然有临界点. 关键路径也正是研究这个临界点的问题. 在学习关键路径前,先了解一个AOV网 ...
- AOE网与关键路径
声明:图片及内容基于https://www.bilibili.com/video/BV1BZ4y1T7Yx?from=articleDetail 原理 AOE网 关键路径 数据结构 核心代码 Topo ...
- AOE网的关键路径的计算
求关键路径,只需理解顶点(事件)和边(活动)各自的两个特征属性以及求法即可: Ø 先根据首结点的Ve(j)=0由前向后(正拓扑序列)计算各顶点的最早发生时间 Ø 再根据终结点的Vl(j)等于它的V ...
- 教你轻松计算AOE网关键路径(转)
原文链接:http://blog.csdn.net/wang379275614/article/details/13990163 本次结合系统分析师-运筹方法-网络规划技术-关键路径章节,对原文链接描 ...
- 教你轻松计算AOE网关键路径
认识AOE网 有向图中,用顶点表示活动,用有向边表示活动之间开始的先后顺序,则称这种有向图为AOV网络:AOV网络可以反应任务完成的先后顺序(拓扑排序). 在AOV网的边上加上权值表示完成该活动所需的 ...
- SDUT 2498 AOE网上的关键路径
AOE网上的关键路径 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 一个无环的有向图称为无 ...
- 数据结构关于AOV与AOE网的区别
AOV网,顶点表示活动,弧表示活动间的优先关系的有向图. 即如果a->b,那么a是b的先决条件. AOE网,边表示活动,是一个带权的有向无环图, 其中顶点表示事件,弧表示活动,权表示活动持续时间 ...
- AOV图与拓扑排序&AOE图与关键路径
AOV网:所有的工程或者某种流程可以分为若干个小的工程或阶段,这些小的工程或阶段就称为活动.若以图中的顶点来表示活动,有向边表示活动之间的优先关系,则这样活动在顶点上的有向图称为AOV网. 拓扑排序算 ...
随机推荐
- AIX 常用命令汇总(一)
命令 内核 如何知道自己在运行 32 位内核还是 64 位内核? 要显示内核启用的是 32 位还是 64 位,可输入以下命令: bootinfo -K 如何知道自己在运行单处理器还是多处理器内核? / ...
- 记录,javascript中对象的属性名是字符串,却可以不用引号
问题描述:今日看书,里面介绍js的对象的属性名是包括空字符串在内的所以字符串 问题来了,我们平时定义的对象如下,是没有引号""or’'的 var someone = { f ...
- codeforces 712 Memory and De-Evolution
2019-05-19 13:25:37 加油,加油,坚持,坚持!!! 一定要逆推,才可以是最少的次数 更好的方法: https://www.cnblogs.com/ECJTUACM-873284962 ...
- B - Beautiful Year
Problem description It seems like the year of 2013 came only yesterday. Do you know a curious fact? ...
- Super超级ERP系统---(4)采购管理--采购单创建
Erp系统中采购是系统必不可少的一部分,也就是ERP种的进货模块,超级ERP系统中的采购模块选选择采购供应商,然后选择进货商品的数量和采购价格,创建采购进货单 1.创建采购单 2.审核采购单 采购单创 ...
- jQuery动画知识总结
jQuery动画概述 我们之前实现的下拉菜单的案例,是没有动画效果的,但是在日常开发中,动画效果是经常会用到的,所以我们可以尝试使用jQuery动画,将下拉菜单案例实现的更动感一些. jQuery提供 ...
- 最简单的一致性Hash算法实现
import java.util.Collection;import java.util.SortedMap;import java.util.TreeMap; public class Consis ...
- 工厂模式-CaffeNet训练
参考链接:http://blog.csdn.net/lingerlanlan/article/details/32329761 RNN神经网络:http://nbviewer.ipython.org/ ...
- Swift - 关键字(typealias、associatedtype)
Typealias typealias 是用来为已经存在的类型重新定义名字的,通过命名,可以使代码变得更加清晰.使用的语法也很简单,使用typealias 关键字像使用普通的赋值语句一样,可以将某个已 ...
- String、Stringbuffer、StringBuffer回顾
前言: 久了没用到,一下子就忘了..,参考文章:https://www.cnblogs.com/su-feng/p/6659064.html.https://baijiahao.baidu.com/s ...