拓撲排序是關鍵路徑求解的前提條件,與拓撲排序相關的資料結構叫做aov網(activity on vertex network),即活動在頂點上的網,在網中若有從頂點i出發,指向頂點j的一條邊,那麼稱頂點i為頂點j的前驅,頂點j為頂點i的後繼,作為時間來表示的話那麼就表示頂點i表示的事件完成了之後才能開始頂點j的事件。
拓撲排序就是用來求解乙個行之有效的工作序列的演算法。
演算法描述如下:
(1)隨機取乙個沒有入度的頂點,將其和從其出發的邊刪除(也就是有些頂點的入度需要減一)
(2)重複(1)的步驟直到沒有頂點位置,如果還有頂點有入度沒有刪除,那麼就證明圖有環,不存在拓撲序列
如上圖是書上的乙個例子
//拓撲排序//
void topologicalsort(adjgraph *g)
} printf("拓撲排序的結果為:\n");
gettop = stack[top--];//取出棧頂元素
printf("%d", g->adjlist[gettop].data);
count++;//進行計數
for (e = g->adjlist[gettop].firstedge; e; e = e->next)
} while (top != 0)
} }printf("\n");
if (count == g->vex_num)
else
}
關鍵路徑涉及到的資料結構是aoe網(activity on edge),其中頂點表示事件,或者(表示活動的開始或者結束),邊的權值為活動所需要的時間。
開始的事件為源點,其入度為0;結束的事件為匯點,其出度為0。
所謂關鍵路徑就是指最晚開始時間和最早開始時間相等的活動所構成的一條路徑。
在這裡我們把路徑長度定義為所經過邊的權值之和。
為了求得關鍵路徑,我們需要求4個變數,他們分別是事件的最早開始時間ve,事件的最晚開始時間vl活動的最早開始時間ee和活動的最晚開始時間el
接下裡我們來介紹四個變數的值
事件最早開始時間ve:源點的ve為0,假設要求ve(j),那麼ve(j)=max,其中wij為從i到j的邊的權值
事件最晚開始時間vl:匯點的最晚開始時間為其ve值,那麼ve(j)=min,其中wjk為從j到k的邊的權值
活動的最早開始時間ee:對於活動ai,其邊是從i指向j的一條權重為wij的邊,那麼ee(i)=ve(i)
活動的最晚開始時間el:對於活動aj,其邊是從j指向k的一條權重為wjk的邊,那麼el(j)=vl(k)-wjk
同樣使用的是鄰接表儲存的圖結構
//關鍵路徑//
int *etv, *ltv;//表示事件最早發生時間和時間最遲發生時間
int *stack2;//為最遲事件發生時間提供儲存
int top2;//stack2的棧頂指標
//改進版的拓撲排序
void topologiaclsortpro(adjgraph *g)
top2 = 0;
etv = (int *)malloc(g->vex_num * sizeof(int));//事件最早發生時間
for (i = 0; i < g->vex_num; i++)
stack2 = (int *)malloc(g->vex_num * sizeof(int));
printf("拓撲排序的結果為:\n");
gettop = stack1[top--];
count++;
stack2[++top2] = gettop;//出棧了之後如stack2,為的是計算事件最晚開始時間
printf(" %d", g->adjlist[gettop].data);
for (e = g->adjlist[gettop].firstedge; e; e = e->next)
if (etv[gettop] + e->weight > etv[k])
} while (top != 0)
if (etv[gettop] + e->weight > etv[k])
} }if (count == g->vex_num)
else
printf("事件最早開始時間為:\n");
for (int i = 0; i < g->vex_num; i++)
printf("\n");
for (int i = 0; i < g->vex_num; i++)
printf("\n");}
//關鍵路徑
void criticalpath(adjgraph *g)
printf("關鍵路徑為:\n");
while (top2 != 0)
} //計算ete和lte來判斷關鍵路徑
//這兩個實際上就是邊
for (j = 0; j < g->vex_num; j++)
}} }
printf("\n");
printf("事件最晚開始時間為:\n");
for (int i = 0; i < g->vex_num; i++)
printf("\n");
for (int i = 0; i < g->vex_num; i++)
}
資料結構與演算法(C語言) 拓撲排序 關鍵路徑
乙個無環的有向圖稱為無環圖 directed acyclic graph 簡稱dag圖。在乙個表示工程的有向圖中,用頂點表示活動,用弧表示活動之間的優先關係,這樣的有向圖為頂點表示活動的網,我們稱之為aov網 active on vertex network aov網不能存在迴路!拓撲序列 設g v...
資料結構與演算法12 拓撲排序和關鍵路徑
有向無環圖及其應用 乙個無環的有向圖稱做有向無環圖,簡稱dag圖。dag圖是一類較有向樹更一般的特殊有向圖。拓撲排序 通常我們把計畫 施工過程 生產流程 程式流程等都當成乙個工程,乙個大的工程常常被劃分成許多較小的子工程,這些子工程稱為活動。這些活動完成時,整個工程也就完成了。例,計算機專業學生的課...
拓撲排序與關鍵路徑
什麼是拓撲排序 設g v,e 是乙個具有n個頂點的有向圖,v中頂點序列v1,v2,vn,稱為乙個拓撲序列,當且僅當該頂點序列滿足下列條件 若是圖中的邊 或從頂點i到j有一條路徑 則在拓撲序列中頂點i必須排在頂點j之前。在乙個有向圖中找 乙個拓撲序列的過程稱為拓撲排序。拓撲排序步驟 1 從有向圖中選擇...