求AOE網中的所有關鍵活動

2021-09-19 01:34:01 字數 4715 閱讀 3150

一、拓撲排序

設g=是乙個具有n個頂點的有向圖,v中的頂點序列v1,v2,v3,...,vn稱為乙個拓撲序列。若是圖中的一條邊或者從頂點vi到頂點vj有路徑,則在該序列中頂點vi必須排在頂點vj之前。

在乙個有向圖中找乙個拓撲序列的過程稱為拓撲排序。

用頂點表示活動,用有向邊表示活動之間的優先關係的有向圖稱為頂點表示活動的網。

拓撲排序方法如下:

1、從有向圖中選擇乙個沒有前驅(即入度為0)的頂點並且輸出它。

2、從圖中刪去該頂點,並且刪去從該頂點發出的全部有向邊。

3、重複上述兩步,直到剩餘的圖中不再存在沒有前驅的頂點為止。

這樣的操作結果有兩種:一種是圖中全部頂點都被輸出,即該圖中所有頂點都在其拓撲序列中,這說明圖中不存在迴路;另一種是圖中頂點未被全部輸出,這說明圖中存在迴路。所以可以通過對乙個有向圖進行拓撲排序,看是否產生全部頂點的拓撲序列來確定該圖中是否存在迴路。

二、aoe網與關鍵路徑

有向無環圖描述工程的預計進度,以頂點表示事件,有向邊表示活動,邊e的權c(e)表示完成活動e所需的時間,或者說活動e持續時間。圖中入度為0的頂點表示工程的開始事件,出度為0的頂點表示工程結束事件,稱這樣的有向圖為邊表示活動的網(aoe網)。

通常每個工程都只有乙個開始事件和乙個結束事件,因此表示工程的aoe網都只有乙個入度為0的頂點,稱為源點,和乙個出度為0的頂點,稱為匯點。如果圖中存在多個入度為0的頂點,只要加乙個虛擬源點,使這個虛擬源點到原來所有入度為0的點都有一條長度為0的邊,從而變成只有乙個源點。對存在多個出度為0的頂點的情況做類似的處理。只討論單源點和單匯點的情況。

利用這樣的aoe網能夠計算完成整個工程預計需要多少時間,並找出影響工程進度的「關鍵活動」,從而為決策者提供修改各活動的預計進度的依據。

在aoe網中,從源點到匯點的所有路徑中具有最大路徑長度的路徑稱為關鍵路徑。完成整個工程的最短時間就是aoe網中關鍵路徑的長度,或者說是aoe網中一條關鍵路徑上各活動持續時間的總和,把關鍵路徑上的活動稱為關鍵活動。關鍵活動不存在富餘的時間,而非關鍵活動可能存在富餘的時間。通常乙個aoe網可能存在多條關鍵路徑,但它們的長度是相同的。

因此,只要找出aoe網中的所有關鍵活動也就找到了全部的關鍵路徑。

/***    實驗題目:

*        求aoe網中的所有關鍵活動

*    實驗目的:

*        領會拓撲排序和aoe網中關鍵路徑的求解過程及其演算法設計

*    實驗內容:

*        設計程式,求如下圖8.45所示的aoe網的所有關鍵活動

#define inf     32767               //定義∞

#define maxv    100                 //最大頂點個數

typedef char infotype;

/*-------------------------以下定義鄰接矩陣型別---------------------------*/

typedef struct

vertextype;                        //頂點型別

typedef struct

matgraph;                          //完整的圖鄰接矩陣型別

//鄰接表表示法-將每個頂點的鄰接點串成乙個單鏈表

/*-----------以下定義鄰接表型別--------------*/

typedef struct arcnode

arcnode;                           //邊結點型別

typedef struct vnode

vnode;                             //鄰接表結點型別

typedef struct

adjgraph;                          //完整的圖鄰接表型別

/*-------------------------鄰接矩陣的基本運算演算法---------------------------*/

/*------------由邊陣列a、頂點數n和邊數e建立圖的鄰接矩陣g--------------------*/

void createmat(matgraph &g, int a[maxv][maxv], int n, int e)

/*------------輸出鄰接矩陣g--------------------*/

void dispmat(matgraph g)

printf("\n");}}

/*-------------------------鄰接表的基本運算演算法---------------------------*/

/*-------------------由邊陣列a、頂點數n和邊數e建立圖的鄰接表g--------------------*/

void createadj(adjgraph *&g, int a[maxv][maxv], int n, int e)

for(i = 0; i < n; i++)                              //檢查鄰接矩陣中的每個元素}}

g->n = n;

g->e = e;

}/*-------------------輸出鄰接表g--------------------*/

void dispadj(adjgraph *g)

printf("∧\n");}}

/*-------------------銷毀圖的鄰接表g--------------------*/

void destroyadj(adjgraph *&g)

free(pre);}}

free(g);                                            //釋放頭結點陣列

}typedef struct keynodekeynode;                                   // 關鍵活動型別

/*---------------------由含有n個頂點的有向圖g產生乙個拓撲序列--------------------*/

static bool topsort(adjgraph *g, int topseq)

}for(i = 0; i < g->n; i++)

}while(top > -1)

p = p->nextarc;                 // 找下乙個鄰接點}}

if(n < g->n)

return false;                       // 拓撲序列中不含所有頂點時

else

printf("\n");

return true;}}

/*---------------------從圖鄰接表g中求出從源點inode到匯點enode的關鍵活動[0...d]----------------------*/

static bool keypath(adjgraph *g, int &inode, int &enode, keynode keynode, int &d) // 引用型別

}for(i = 0; i < g->n; i++)               // 先將所有事件的vl值置為最大值

vl[i] = ve[enode];

for(i = g->n - 2; i >= 0; i--)

}d = -1;                                 // d存放keynode中的關鍵活動下標,置初值為-1

for(i = 0; i < g->n; i++)

p = p->nextarc;}}

return true;

}/*---------------------輸出圖g的關鍵活動----------------------*/

static void dispkeynode(adjgraph *g)

else

printf("不能求關鍵活動\n");

}int main(void)

/*a*/,/*b*/,

/*c*/, /*d*/,

/*e*/, /*f*/,

/*g*/, /*h*/,

/*i*/

};printf("建立圖的鄰接表:\n");

createadj(g, a, n, e);

printf("圖g的鄰接表:\n");

dispadj(g);

dispkeynode(g);         // 求構成關鍵路徑的關鍵活動

destroyadj(g);

return 0;

}測試結果:

建立圖的鄰接表:

圖g的鄰接表:

頂點0:   1[6]->  2[4]->  3[5]->∧

頂點1:   4[1]->∧

頂點2:   4[1]->∧

頂點3:   7[2]->∧

頂點4:   5[9]->  6[7]->∧

頂點5:   8[2]->∧

頂點6:   8[4]->∧

頂點7:   8[4]->∧

頂點8: ∧

拓撲序列:a d h c b e g f i

從源點a到匯點i的關鍵活動:(a,b) (b,e) (e,f) (e,g) (f,i) (g,i)

AOE網求關鍵路徑(關鍵活動)

aoe網求關鍵路徑 關鍵活動 aoe網求解關鍵路徑,所需的是有向無環圖 利用拓撲排序,如果序列長度為頂點數,則是無環,小於頂點數則是有環圖,有環圖是不滿足求aoe網的 注意的是,只有乙個源點,有乙個匯頂點,然後關鍵路徑不一定只有一條。注意,這裡要理解 頂點 事件 邊 活動 還有四個陣列下面有介紹 這...

求關鍵路徑 邊活動網(AOE)

題目大意 前提 有向無環圖 dag 才有解。aoe網 邊活動網 點為事件,帶權的邊集為活動,權為完成活動所需要的時間。求計算完成總事件的最短時間。即求最長路徑 此處最長即完成所有關鍵活動,即滿足了實現總事件的最短時間問題。思路 先求點,再求邊。求最長路徑 求所有關鍵活動 判斷是否為關鍵活動 最遲開始...

AOE網列印所有的關鍵路徑

思路是因為aoe網的關鍵路徑就是起點到終點的最長路徑 起點是入度為0的點,終點是出度為0的點 於是先用spfa求出起點到終點的最長距離,然後再用dfs求起點到終點的最長距離的路徑結果保留在ans陣列.include include include include includeusing names...