`

图的关键路径

阅读更多

求关键路径的算法:

1)输入e条弧<i,j>,建立AOE网的存储结构。

2)从源点v0出发,令ve[0]0按拓扑有序求其余各顶点的最早发生时ve[i]1i n-1)。如果得到的拓扑有序序列中顶点个数小于网中顶点数n,则说明网中存在环,不能求关键路径,算法终止;否则执行步骤(3)。

3)从汇点vn出发,令vl[n-1]= ve[n-1],按逆拓扑有序求其余各顶点的最迟发生时间vl[i] (n-2 i 0)

4)根据各顶点的vevl值,求每条弧s的最早开始时间e(s)和最迟开始时间l(s)。若某条弧满足条件e(s)=l(s),则为关键活动。

                   

#include<iostream>
using namespace std;
#define MAX_VEXTEX_NUM 20
#define M 20
#define MaxLen 1000    //最大长度
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int SElemType;
typedef int VertexType;
typedef int VRType;
typedef int InfoType;
typedef struct ArcNode
{
int adjvex; // 该弧所指向的顶点的位置
    struct ArcNode *nextarc;// 指向下一条弧的指针
InfoType   info;   // 该弧相关信息的指针
}ArcNode;
typedef struct VNode
{
VertexType data;// 顶点信息
    ArcNode *firstarc;// 指向第一条依附该顶点的弧
}VNode,AdjList[MAX_VEXTEX_NUM];
typedef struct
{
AdjList vertices;
    int vexnum, arcnum;
}ALGraph;
typedef struct SqStack
{
SElemType *base;
    SElemType *top;
    int stacksize;
}SqStack;

 

void InitStack(SqStack &S)//初始化栈
{
S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S.base)
   exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
int Pop(SqStack &S,SElemType &e)//出栈操作
{
if(S.top==S.base)return ERROR;
e=*--S.top;
return OK;
}
int Push(SqStack &S,SElemType e)//人栈操作
{
if(S.top-S.base>=S.stacksize)
{
   S.base = (SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
   if(!S.base)
    exit(OVERFLOW);
   S.top = S.base+S.stacksize;
   S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return OK;
}
int StackEmpty(SqStack S)//判栈是否为空
{
if(S.top==S.base)
   return OK;
else
   return ERROR;
}
int CreatALGraph(ALGraph &G)//构建图
{
ArcNode *p;
int i, j, k,info1;
cout<<"请输入有向图的顶点数和弧数:"<<endl;
cout<<"vexnum:";
cin>>G.vexnum;
cout<<endl<<"arcnum:";
cin>>G.arcnum;
for (i=1;i<=G.vexnum;i++)
{
   G.vertices[i].data=i;
   G.vertices[i].firstarc=NULL;
}
for(k=1;k<=G.arcnum;k++)       //输入存在边的点集合
{
   cout<<"建立弧,请输入第"<<k<<"条弧对应的顶点序号及权值:";
   cin>>i>>j>>info1;
        if(i==j||i<0||j<0)
   {
    cout<<"i,j,不合法输入"<<endl;
    cout<<"请重新输入"<<k<<"条弧对应的顶点:";
    cin>>i>>j;
   }
   if(i>G.vexnum||j>G.vexnum)
   {
    cout<<"图中没有这样的点,重新输入:"<<endl;
    cout<<"请重新输入"<<k+1<<"条弧对应的顶点:";
    cin>>i>>j;
   }
   p=(ArcNode*)malloc(sizeof(ArcNode));
   p->adjvex=j;
   p->info=info1;
   p->nextarc=G.vertices[i].firstarc;
   G.vertices[i].firstarc=p;
}
return OK;
}
void FindInDegree(ALGraph G,int indegree[])//求入度操作
{
int i;
for(i=1;i<=G.vexnum;i++)
{
   indegree[i]=0;
}
for(i=1;i<=G.vexnum;i++)
{
   while(G.vertices[i].firstarc)
   {
    indegree[G.vertices[i].firstarc->adjvex]++;
    G.vertices[i].firstarc=G.vertices[i].firstarc->nextarc;
   }
}
}
int ve[100];
int TopologicalSort(ALGraph G,SqStack &T)       //进行拓扑排序
{
int indegree[M];
FindInDegree(G, indegree);//求各顶点的入度
    SqStack S;
int i,x,k;

InitStack(S);
ArcNode *p;
InitStack(S);
for (i=1;i<=G.vexnum;i++)
{
   if (!indegree[i])Push(S,i);//入度为0者入栈
}
InitStack(T);
int count=0;
for(x=1;x<=G.vexnum;x++)// ve[0..G.vexnum-1]=0;
{
   ve[x]=0;  
}
while(!StackEmpty(S))
{
   Pop(S,i);
   Push(T,i);
   ++count;//输出i号顶点并计数
   for (p=G.vertices[i].firstarc;p;p=p->nextarc)
   {
    k=p->adjvex;
    if (--indegree[k]==0)//若入度减为0,则入栈
    {
     Push(S,k);
    }
    if((ve[i]+p->info)>ve[k])
    {
     ve[k]= ve[i]+p->info;
    }

   }

}
cout<<endl;
if (count<G.vexnum)//该图有回路
{
   cout<<"出现错误"<<endl;
}
else
{
   cout<<"排序成功"<<endl;
}
return OK;
}
int CriticalPath(ALGraph G)//输出G的关键活动
{
int dut;
int j=G.vexnum;
int i,k;
int ee,el;
char tag;
int vl[100];
ArcNode *p;
SqStack T;
if(!TopologicalSort(G,T))
{
   printf("该图存在环,无法找到关键路径!");
   return ERROR;
}
for(i=1;i<=G.vexnum;i++)// vl[0.. G.vexnum-1] =ve[0..G.vexnum-1];//用ve初始化vl
{
   vl[i]=ve[G.vexnum];
}
printf("带*的为关键活动!\n");
printf("起点\t终点\tdut\tee\tel\ttag\n");
    while(!StackEmpty(T))  
   for(Pop(T,j),p=G.vertices[j].firstarc;p;p=p->nextarc)
   {
    k=p->adjvex;
    dut=p->info;
    if((vl[k]-dut)<vl[j])
    {
     vl[j]=vl[k]-dut;
    }
   }//end of for
   for(i=1;i<=G.vexnum;++i)
    for (p=G.vertices[i].firstarc;p;p=p->nextarc){
     k=p->adjvex;
     dut=p->info;
     ee=ve[i];
     el=vl[k]-dut;
     tag=(ee==el)?'*':' ';
     printf("%d\t%d\t%d\t%d\t%d\t%c\n",i,k,dut,ee,el,tag);
    }//end of for(p)
    return 1;
}//end of CriticalPath
int main()
{
ALGraph G;
CreatALGraph(G);
CriticalPath(G);
    return 0;
}

分享到:
评论

相关推荐

    活动图关键路径1

    活动图是一种流程建模工具,常用于描述系统中任务或事件的流程,特别是在项目管理中,它可以用来识别关键路径,这是理解项目进度和优化资源分配的关键。关键路径法(Critical Path Method, CPM)是确定项目中最关键...

    图关键路径(C语言)

    根据给定的文件信息,我们可以深入探讨图的关键路径算法在C语言中的实现,以及与之相关的数据结构和算法概念。 ### 图关键路径算法 图的关键路径算法通常用于解决任务依赖问题,例如项目管理中的活动网络图(AOV网...

    有向图关键路径问题 三种算法求解

    根据给定的信息,本文将详细解释“有向图关键路径问题及三种算法求解”的相关知识点,包括背景介绍、关键路径问题定义、三种算法(拓扑排序法、Dijkstra算法变体以及深度优先搜索法)的原理与实现,并对部分代码进行...

    有向图关键路径

    有向图关键路径是图论中的一个重要概念,广泛应用于项目管理、计算机科学和工程领域,以确定任务依赖关系和最迟开始时间。在本场景中,我们关注的是如何在有向无环图(DAG)中找到从源节点到目标节点的最长路径,这...

    java实现带权无环图关键路径查找

    在这个场景中,我们关注的是如何使用Java编程语言来实现对带权无环图(Weighted Acyclic Graph,WAG)的关键路径查找算法。 首先,我们要理解什么是带权无环图。在图论中,一个无环图是指没有形成环路的图,而带权...

    关键路径,你懂的.有向图

    关键路径分析首先需要构建一个活动-on-edge (AON) 或活动-on-node (AON) 的网络图,其中节点表示活动,边表示活动间的先后顺序。有向图可以清晰地展示这些顺序关系,确保没有回路,即图是无环的。为了找到关键路径,...

    图的关键路径求解过程

    图的关键路径是项目管理中的重要概念,用于确定一个有向无环图(DAG,Directed Acyclic Graph)中决定项目最短完成时间的关键任务序列。在这个任务中,AOV网(Activity On Vertex)就是用来表示项目的任务网络图,...

    图的最短路径、拓扑排序和关键路径

    "图的最短路径、拓扑排序和关键路径" 图的最短路径是图论中的一种重要概念,它是指从图的一顶点到另一顶点的路径中,所经过的边的数目最少的那条路径。这种路径也可以称作最短距离或最短路径长度。在无权图中,图的...

    图的关键路径-数据结构

    在这个场景中,"图的关键路径-数据结构"涉及到的是在图中寻找关键路径的方法。首先,我们需要理解拓扑排序,它是将有向无环图的所有节点排列成线性顺序的一种方式,使得对于每条有向边 (u, v),节点 u 都在节点 v ...

    找图的关键路径的算法

    基于graph类的找有向图的中关键路径算法

    课程设计-树的关键路径(C)

    关键路径通常在有向无环图(DAG)中进行计算,其中节点代表任务,边代表任务之间的依赖关系。关键路径算法的目标是找到所有可能路径中耗时最长的一条路径,这条路径上的任务就是项目中的关键任务。 ### C语言实现关键...

    c++关键路径源代码

    在软件开发中,关键路径(Critical Path)是一种项目管理技术,用于确定项目中哪些任务是最重要的,以及这些任务如何影响项目的整体进度。在C++编程中实现关键路径可以帮助开发者优化资源分配,确保项目按时完成。...

    关键路径图及算法题

    关键路径图及算法题的ppt ,比较有效的 密码:hbsoft.net336*ABC 选择只读就可以看了

    求AOE网络关键路径

    通过深入研究并实践这段代码,开发者不仅可以掌握关键路径的概念,还能增强对C++编程语言的理解,尤其是数据结构(如队列和栈)和图算法的应用。此外,对于项目管理和工程调度领域的人来说,理解并能运用AOE网络和...

    数据结构中关键路径算法的实现与应用

    ### 数据结构中关键路径算法的实现与应用 #### 一、引言 在项目管理和软件工程领域,关键路径方法(Critical Path Method, CPM)是一种用于计划和控制大型项目的统计工具,它帮助确定项目的最短完成时间,并指出...

    图的关键路径算法实现.zip

    图的关键路径算法是一种在图论中用于寻找项目或任务依赖关系网络中最长路径的方法,它在项目管理和软件工程等领域有着广泛的应用。这个压缩包文件"图的关键路径算法实现.zip"包含了一个C语言实现的关键路径算法,是...

    图的深度广度遍历,关键路径和最短路径

    总结以上,图的深度优先和广度优先遍历是基础的图遍历方法,关键路径和最短路径算法则用于解决实际问题,如项目管理、网络优化等。邻接表法作为一种高效的数据结构,有助于我们更好地操作和理解图的性质。

    C语言求AOE网关键路径

    标题中的"C语言求AOE网关键路径"是指利用C语言编程来解决活动网络图(Activity On Edge, AOE)中的关键路径问题。关键路径是项目管理中的一个重要概念,它表示了从项目开始到结束的最长路径,决定了项目的最短完成...

    用c#写的关键路径算法

    在C#编程中,关键路径算法(Critical Path Method, CPM)是一种用于项目管理的技术,它可以帮助确定项目中哪些任务是关键的,即任何延迟都会导致整个项目延期的任务。以下是一个使用C#实现的关键路径算法的基本框架...

    拓扑排序关键路径算法C语言完整代码

    在有向图中,关键路径可以通过计算每个活动的最早开始时间和最晚结束时间(ES, LS)以及它们的浮动时间(TF)来确定。 **C语言实现** 在提供的`CriticalPath.c`和`CriticalPath.h`文件中,我们可以看到一个实现拓扑...

Global site tag (gtag.js) - Google Analytics