`
evasiu
  • 浏览: 169486 次
  • 性别: Icon_minigender_2
  • 来自: 广州
博客专栏
Fa47b089-e026-399c-b770-017349f619d5
TCP/IP详解卷一>阅读...
浏览量:12549
社区版块
存档分类
最新评论

图论--关键路径

阅读更多

最近忙着做作业。主要是《代数与图论》的一些算法的实现,五一估计不用过了,数据压缩要看论文,信息检索要做实验,实验室还要实现模糊匹配的改进。。。我怎么选了这么些难搞的课啊。。编程珠玑看来要被无限地搁置了

 

说一下关键路径的实现吧。

其实主要也是从网上看来的。

 

关键路径的相关概念:

 

1. AOE图:在工程上,很多任务之间常常有先后顺序的要求,例如,建房子前要先打桩等。任务与任务之前有前后顺序要求时,在图上表现为一个有向边,从任务(1)指向任务(2),并且这中间需要一定的时间间隔,往往把时间间隔做为两个任务间的边的权重。这样的图叫AOE图(Activity on Edge)。下图即为一个AOE图(呵呵,我也是从某个PPT上拷下来的):


 

2. 最早发生时间:最早发生时间是指从源点v1到任意vi的最长路径,叫事件中vi的最早发生时间。(因为必须等前面需要完成的任务都完成后,才能做vi)

     设ve(i)为vi的最早发生时间,有ve(1)=0, ve(i) = max{ve(i)+dut<j,k>}, <i,j>is in T

     T是所有以j为弧头的弧集合,dut<i,j>表示从i到j需要的时间。

     (如上图结点7, ve(7)=max{ve(4)+a8, ve(5)+a2})

3. 最迟发生时间:最迟发生时间是指从在不推迟整个工程完成的前提下,ai的最迟必须开始进行的时间。

    设vl(i)为vi的最迟发生时间,有vl(n)=ve(n), vl(i) = min{vl(j)-dut<i,j>}, <i j>is in S

    S是所有以i为弧尾的弧的集合.

    (如上图,vl(5)=min{vl(7)-a5, vl(8)-a10})

4. 当ve(i)+dut<i,j>=vl(j)时,弧<i, j>为关键路径上的弧。

 

这样的话,我们可以先通过拓扑排序一路计算出每个结点的最早发生时间,最后将ve(n)赋予vl(n)然后再一路返回来求每个结点的最迟发生时间,即可求出关键路径上的弧了。

 

算法流程主要是做拓扑排序,这个过程可以顺便求出各个结点的最早发生时间。求结点的最迟发生时间是一个逆排序过程。具体实现的时候,我把队列做成两头通的,用front和rear来表示队列的头部跟尾部。拓扑排序的时候从队尾加进去,逆排序的时候从队尾取出来。

首先是数据结构的表示。我用一个邻接表表示一个图。因为做拓扑排序的时候,我是通过将入度为0的点压入栈中,所以在邻接表的头部我记录了相关顶点的入度。

 

具体代码如下:

#include<stdio.h>

//邻接结点的ID及边上的权重。
typedef struct Node{
	int nodeID;
	int dut;
	struct Node* next;
}adjNode;

//表头,结点nodeID的入度,邻接结点
typedef struct{
	int indgr;
	int nodeID;
	adjNode* adj;
	adjNode* tail; //为方便加入新结点而设计的。
}vexNode;

void criticalPath( vexNode* g, int numP ){
	//data structure for calculation
	int* stack = (int*)malloc( sizeof(int)*numP );
	int front = 0, rear = -1;
	int* ve = (int*)malloc( sizeof(int)*numP );
	int* vl = (int*)malloc( sizeof(int)*numP );
	int i;
	for( i=0; i<numP; i++ )	
		if( g[i].indgr == 0 )	
			stack[++rear] = i;
	for( i=0; i<numP; i++ ) ve[i] = 0;
	while( rear>=front ){
		int j=stack[front++];
		adjNode* tmp;
		for( tmp=g[j].adj; tmp!=NULL; tmp=tmp->next ){
			(g[tmp->nodeID].indgr)--;
			if( g[tmp->nodeID].indgr == 0 )
				stack[++rear]=tmp->nodeID;
			//calculate the earliest start time
			if( ve[tmp->nodeID] < ve[j]+tmp->dut )
				ve[tmp->nodeID] = ve[j]+tmp->dut;
			}
		}
	if( rear < numP-1 ){
		printf( "circle in the graph\n" );
		return ;
	}
	
	//lastest start time
	for( i =0; i<numP; i++ )
		vl[i] = ve[numP-1];
	
	while( rear>=0 ){
		int j=stack[rear--];
		adjNode* tmp;
		for( tmp=g[j].adj; tmp!=NULL; tmp=tmp->next ){
			if( vl[j] > vl[tmp->nodeID] - tmp->dut )
				vl[j] = vl[tmp->nodeID] - tmp->dut;
			}
		}
		
	front = 0;
	rear = numP-1;
	//collect the critical tasks
	while( rear>=front ){
		int j=stack[front++];
		adjNode* tmp;
		for( tmp=g[j].adj; tmp!=NULL; tmp=tmp->next ){
			if( ve[j] == vl[tmp->nodeID]-tmp->dut )
				printf( "<%d, %d>\n", j, tmp->nodeID );
			}
		}
	free( stack );
 	free( ve );
 	free( vl );
}

main(){
	int verNum, actNum;
	int i;
	printf( "enter the number of vertices: " );
	scanf( "%d", &verNum );
	vexNode* g = (vexNode*)malloc( sizeof(vexNode)*verNum );
	//initialization
	for( i=0; i<verNum; i++ ){
		g[i].indgr = 0;
		g[i].nodeID = i;
		g[i].adj = NULL;
		g[i].tail = NULL;
	}
	printf( "\nhow many activities are there? " );
	scanf( "%d", &actNum );
	printf( "\nenter them in the form of | startNode endNode duration | one by one\n" );
	int tmpS, tmpE, tmpD;
	//construct the map for the project
	for( i=0; i<actNum; i++ ){
		scanf( "%d %d %d", &tmpS, &tmpE, &tmpD );
		(g[tmpE].indgr)++;
		adjNode* tmpN = (adjNode*) malloc( sizeof(adjNode) );
		tmpN->nodeID = tmpE;
		tmpN->dut = tmpD;
		tmpN->next = NULL;
		if( g[tmpS].tail == NULL ){
			g[tmpS].adj = tmpN;
			g[tmpS].tail = tmpN;
		}else{
			g[tmpS].tail->next = tmpN;
			g[tmpS].tail = tmpN;
		}
	}
	//search the critical path
	criticalPath( g, verNum );
}
		

 

 

 

  • 大小: 26.4 KB
分享到:
评论

相关推荐

    图论- AOE 网与关键路径.rar

    掌握图论中的AOE网与关键路径知识对于软件开发、系统分析、项目管理等领域的专业人士来说极为重要,它可以帮助他们更高效地规划和执行复杂项目,提高工作效率,减少不必要的延误。因此,深入理解和应用这些理论是...

    哈尔滨工业大学图论-总结-CSDN下载

    这里我们将围绕"哈尔滨工业大学图论-总结"这一主题,深入解析其中可能涵盖的关键知识点。 1. 图的基本概念: - 图是由顶点(Vertex)和边(Edge)构成的数据结构,可以用来表示各种关系。边连接两个顶点,无向图的...

    图论- 环与块- 最小环.rar

    总的来说,图论的环与块是分析复杂系统连接性的关键工具,最小环的识别对优化问题至关重要。通过学习相关理论和算法,我们可以更好地理解和解决实际问题。阅读"图论- 环与块- 最小环.pdf"这份资料,将有助于深化你对...

    图论- 图的搜索.rar

    在这个压缩包“图论- 图的搜索.rar”中,我们主要可以学习到关于图的深度优先搜索(DFS)和广度优先搜索(BFS)这两个关键算法。 深度优先搜索是一种用于遍历或搜索树或图的算法。在图中,DFS会尽可能深地探索图的...

    集合与图论- 计算机学院课件

    在计算机科学中,图论的应用无处不在,如网络设计、任务调度、最短路径问题、社交网络分析等。关键概念包括无向图、有向图、邻接矩阵、邻接表、连通性、树、生成树、环、桥、二分图等。深度优先搜索(DFS)和广度...

    图论- 生成树- 最小瓶颈路.rar

    在这个主题中,“生成树”和“最小瓶颈路”是两个关键概念,它们在图论算法中有着广泛的应用,特别是在网络设计、路径优化、数据结构等领域。 生成树是指在一个无环连通图(即无向图或有向图)中找到一个子集,这个...

    图论- 弦图- LexBFS 算法.rar

    弦图的一个关键特性是,它能简化复杂网络的表示,帮助我们理解和解决涉及这些网络的问题。 接下来,我们转向Lex BFS算法,这是一种对图进行遍历的特殊方法。广度优先搜索(BFS)是一种基础的图遍历算法,它从一个...

    图论- 二分图- 匈牙利算法.rar

    匈牙利算法的一个关键特性是它总是能找到最大匹配,而且时间复杂度为O(n^3),其中n是图中节点的数量。这使得它在处理中等规模问题时非常有效。 在实际应用中,匈牙利算法不仅可以解决二分图的最大匹配问题,还可以...

    图论- 网络流- 最大流- SAP 算法与 ISAP 算法.rar

    在本压缩包文件中,我们将探讨两个关键的算法:SAP(Shortest Augmenting Path)算法和ISAP(Iterative Shortest Augmenting Path)算法,它们都是求解网络最大流问题的有效方法。 最大流问题是寻找网络中从源点到...

    图论- 环与块.rar

    图论是离散数学的一个重要分支,主要研究图的结构、性质及其应用。在这个主题中,"环"和"块"是两个核心概念,它们在理解图的连通性、分解以及复杂网络分析中起到关键作用。让我们深入探讨这两个概念。 环是指在图中...

    图论- 图的遍历.rar

    在图论中,图的遍历是一个基础且关键的概念,它涉及到如何系统地访问图中的每一个顶点。这里我们将深入探讨图的遍历方法——深度优先搜索(DFS)和广度优先搜索(BFS)。 1. 深度优先搜索(DFS) DFS 是一种用于...

    图论- 网络流- 最小割- 平面图与对偶图.rar

    平面图的概念在计算机图形学、电路设计等领域非常关键,因为它允许我们将复杂的问题分解为二维空间内的简单结构。平面图的性质包括欧拉公式(V - E + F = 2,其中V是顶点数,E是边数,F是面数)和四色定理(任何平面...

    图论- 环与块- DAG 图判定.rar

    在图论中,环与块是两个基本概念,尤其在有向无环图(DAG,Directed Acyclic Graph)的分析中,它们扮演着关键角色。 **环与图论** 环在图论中指的是一个起点和终点相同的路径,它构成了一个闭合序列。在无向图中,...

    图论- 图的连通性- Kosaraju 算法.rar

    图的连通性是图论中的核心概念之一,主要关注图中的顶点之间是否存在路径使得它们可以互相到达。 Kosaraju算法是一种用于识别图的强连通分量的算法。强连通分量是图中的一种特殊子图,其中任意两个顶点都是相互可达...

    图论- 图的连通性- 传递闭包.rar

    在图论中,图的连通性是极其关键的概念,它涉及到图中节点之间的路径存在性。传递闭包是图的连通性理论中的一个核心概念,尤其在有向图(也称为有向网络)的分析中具有重要意义。 首先,我们要理解“连通图”的概念...

    图论- 图的连通性- Tarjan 求割点与桥.rar

    当我们探讨图的连通性时,关注的是图中各个顶点之间是否存在路径使得它们可以互相到达。 Tarjan算法是一种求解图的连通性问题的方法,特别用于识别割点(cut vertex)和桥(bridge)。这两个概念对于理解图的结构至...

    图论- 环与块- 连通块的计数.rar

    环是图中的一种特殊结构,指的是起点和终点相同的闭合路径,而连通块则是指图中任意两个顶点之间都存在路径的子图。 在“环与块”的主题中,我们首先要理解环的概念。环是图中一个重要的组成部分,它代表了一条开始...

    2003-集合论与图论-期末试题及答案1

    这些知识点涵盖了集合论的基本概念、图论中的关键术语和性质,以及相关的函数和关系理论,这些都是计算机科学特别是算法和数据结构领域的基础。理解并掌握这些知识有助于解决复杂问题,如图的遍历、搜索和最优化问题...

    图论- 网络流- 基本概念与建模技巧.rar

    网络流问题的建模技巧和算法是解决实际问题的关键。理解并熟练掌握这些概念和方法,能帮助我们设计出更有效的解决方案,解决各种实际场景下的优化问题。通过深入学习和实践,可以进一步探索网络流理论的复杂性和深度...

    图论- 网络流- 最大流- Dinic 算法.rar

    Dinic算法的关键在于其高效的路径查找和增广策略,能够有效地利用网络的局部结构,避免了回溯和无效的流量分配。其时间复杂度通常为O(V^2 * E),其中V是节点数,E是边数。尽管不是最快速的算法(比如Ford-Fulkerson...

Global site tag (gtag.js) - Google Analytics