關鍵路徑

AOE網:在一個表示工程的帶權有向圖中,用頂點表示事件,用有向邊表示活動,用邊上的權值表示活動的持續時間,這種有向圖的邊表示活動的網,我們稱之爲AOE網。

把路徑上各個活動所持續的時間之和稱爲路徑長度,從源點到匯點具有最大長度的路徑稱爲關鍵路徑,在關鍵路徑上的活動叫關鍵活動

關鍵路徑算法:

我們需要定義如下幾個參數:

1、事件的最早發生時間etv:即頂點v的最早發生時間。

2、事件的最晚發生時間ltv:即頂點v的最晚發生時間。也就是每個頂點對應的事件的最晚需要開始的時間,超出此時間將會延誤整個工期。

3、活動的最早開工時間ete:即弧a的最早發生時間。

4、活動的最晚開工時間lte:即弧的最晚發生時間,也就是不推遲工期的最晚開工時間。

有1和2可以求得3和4,然後再根據ete[k]是否與lte[k]相等來判斷a是否是關鍵活動。

求etv的過程,就是從頭到尾找拓撲序列的過程。求ltv就是把拓撲序列倒過來的過程。

此算法的時間複雜度是O(n+e)。

typedef struct EdgeNode
{
	int adjvex;
	int weight;
	struct EdgeNode *next;
} EdgeNode;
typedef struct VertexNode
{
	int in;
	int data;
	EdgeNode *firstedge;
} VertexNode, AdjList[MAXVEX];
typedef struct 
{
	AdjList adjList;
	int numVertexes, numEdges;
} graphAdjList, *GraphAdjList;

int *etv, *ltv;
int *stack2;
int top2;

Status TopologicalSort(GraphAdjList GL)
{
	int i, k, gettop;
	int count = 0;
	int *stack;
	int top = 0;
	EdgeNode *e;

	stack = (int *)malloc(GL->numVertexes * sizeof(int));
	for (i = 0; i < GL->numVertexes; i++)
		if (GL->adjList[i].in == 0)
			stack[++top] = i;

	stack2 = (int *)malloc(GL->numVertexes * sizeof(int));
	etv = (int *)malloc(GL->numVertexes * sizeof(int));
	top2 = 0;
	for (i = 0; i < GL->numVertexes; i++)
		etv[i] = 0;

	
			

	while (top != 0)
	{
		gettop = stack[top--];
		count++;

		stack2[++top2] = gettop;

		for (e=GL->adjList[gettop].firstedge; e; e = e->next)
		{
			k = e->adjvex;

			if (!(--GL->adjList[k].in))
				stack[++top] = k;

			if (e[k] < e[gettop] + e->weight)
				e[k] = e[gettop] + e->weight;
		}
	}

	if (count < GL->numVertexes)
		return ERROR;
	else
		return OK;
}

void CriticalPath(GraphAdjList GL)
{
	int i, j, k, gettop, ete, lte;
	EdgeNode *e;

	TopologicalSort(GL);

	ltv = (int *)malloc(GL->numVertexes * sizeof(int));
	for (i = 0; i < GL->numVertexes; i++)
		ltv[i] = etv[GL->numVertexes - 1];

	while (top2 != 0)
	{
		gettop = stack2[top2--];
		for (e = GL->adjList[gettop].firstedge; e; e = e->next)
		{
			k = e->adjvex;
			if (ltv[gettop] > ltv[k] - e->weight)
				ltv[gettop] = ltv[k] - e->weight;
		}
	}

	for (j = 0; j < GL->numVertexes; j++)
		for (e = GL->adjList[j].firstedge; e; e = e->next)
		{
			k = e->adjvex;
			ete = etv[j];
			lte = ltv[k] - e->weight;
			if (ete == lte)
				printf("<v%d v%d> length %d", GL->adjList[j].data, GL->adjList[k].data, e->weight);
		}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章