日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

拓扑排序--关键路径

發(fā)布時間:2025/6/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 拓扑排序--关键路径 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

拓撲排序和關(guān)鍵路徑是基于無環(huán)的有向圖。

主要用來表示工程進度中各個事件之間的關(guān)系。

?拓撲排序和關(guān)鍵路徑?使用鄰接表存儲數(shù)據(jù),最小生成樹和最短路徑用?鄰接矩陣?存儲數(shù)據(jù)。

1、拓撲排序

AOV網(wǎng):在一個表示工程的有向圖中,用固定點表示活動,用弧表示活動之間的優(yōu)先級關(guān)系,這樣的有向圖為頂點表示活動的網(wǎng),我們稱之為AOV網(wǎng)(Activity?On?Vertex?Network)

拓撲排序:是將一個AOV網(wǎng)的各個頂點按一定順序排列,要求滿足若存在<Vi,Vj>,則排序中的頂點Vi必在頂點Vj之前。對于同一幅圖,拓撲排序可有多個拓撲排序。

在顯示生活中,用到的拓撲排序的例子:

????????學(xué)校課程布置圖,要先修完一些基礎(chǔ)課,才可以繼續(xù)修專業(yè)課,以計算機軟件專業(yè)為例,在《程序設(shè)計基礎(chǔ)》和《離散數(shù)學(xué)》課程學(xué)完之前就不能開始學(xué)習(xí)《數(shù)據(jù)結(jié)構(gòu)》,這些先決條件定義了課程之間的優(yōu)先(領(lǐng)先)關(guān)系。

算法:

(1)從有向圖中選擇一個無前驅(qū)(入度為0)的頂點輸出。

(2)刪除此頂點,并刪除已此頂點為為尾的弧。

(3)重復(fù)(1),(2)步驟,知道輸出全部頂點或者AOV網(wǎng)中不存在入度為0的頂點。

具體實現(xiàn)代碼:

????用棧來保存入度為0的頂點,和更新后入度為0的頂點

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <stdio.h> #define MAXVEX 100 typedef?struct?EdgeNode???/*邊表節(jié)點*/ { int?adjvex;???????/*鄰接點域,存儲該頂點對應(yīng)的下表*/ int?weight;???????/*用于存儲權(quán)值,對于非網(wǎng)圖可以不需要*/ struct?EdgeNode *next;??/*鏈域,指向下一個鄰節(jié)點*/ }EdgeNode; typedef?struct?VertexNode???/*頂點表節(jié)點*/ { int?in;??????????/*頂點入度*/ int?data;???????/*頂點域,存儲頂點信心*/ EdgeNode *firstedge;?/*邊表頭指針*/ }VertexNode, Adjlist[MAXVEX]; typedef?struct { Adjlist adjList; int?numVertexes; int?numEdges;??/*圖中當前頂點數(shù)和邊數(shù)*/ }graphAdjList, *GraphAdjList; /*拓撲排序,若GL無回路,則輸出拓撲排序序列并返回OK,若有回路返回ERROR*/ int?TopoLogicalSort(GraphAdjList GL) { EdgeNode *e; int?i,k,gettop; int?top = 0;???/*用于棧指針下表*/ int?count = 0;?/*用于統(tǒng)計輸出頂點的個數(shù)*/ int?*stack;??/*建棧用于存儲入度為0的頂點*/ stack = (int*)malloc(GL->numVertexes *sizeof(int));??//動態(tài)分配內(nèi)存,大小為n個頂點(最多有n個頂點入度為0,因為圖總共有n個頂點) for(i = 0; i<GL->numVertexes; i++) if(GL->adjList[i].in == 0)??/*將入度為0的頂點入棧*/ stack[++top] = i; while(top != 0) { gettop = stack[top--];??/*出棧*/ printf("%d -> ",GL->adjList[gettop].data);?/*打印此頂點*/ count++;?/*統(tǒng)計輸出頂點數(shù)*/ for(e=GL->adjList[gettop].firstedge; e!; e=e->next) {?/*對此頂點弧表遍歷*/ k = e->adjvex; if(--GL->adjList[k].in == 0)??//將k號頂點鄰接點的入度減1,且減1后,入度為0的頂點需要存到棧中 stack[++top] = k; } } if(count < GL->numVertexes)??/*如果count小于頂點數(shù),說明存在環(huán)*/ return?-1; else return?0; }

?

分析整個算法,對一個具有n個頂點e條弧的AOV網(wǎng)來說,將入度為0的頂點入棧的時間復(fù)雜度為O(n),而之后的while循環(huán)中,每個頂點入一次棧,出一次棧,入度減1的操作執(zhí)行了e次,所以整個算法時間復(fù)雜度為O(n+e)。

2、關(guān)鍵路徑

拓撲排序是解決一個工程能否順序進行的問題,但有時還需解決工程完成需要的最短時間。

AOE網(wǎng):在一個表示工程帶權(quán)的有向圖中,用頂點表示事件,用有向邊表示活動,用邊上的權(quán)值表示活動的持續(xù)時間,這種用有向圖的邊表示活動的網(wǎng),我們稱之為AOE網(wǎng)(Activity?On?Edge?Network)

用ve(i)表示事件(即頂點)i的最早開始時間,用vl(i)表示事件i的最開始時間,如果活動k由弧<m,n>表示,用dut(<m,n>)表示活動的持續(xù)時間,則有:

e(k)?=?ve(m)

l(k)?=?vl(n)?-?dut(<m,n>)

求解關(guān)鍵路徑的具體算法(假設(shè)圖中有n個頂點)

(1)?從開始頂點V0出發(fā),假設(shè)ve(0)=0,然后按照拓撲有序求出其他各頂點i的最早開始時間ve(i),如果得到拓撲序列中頂點數(shù)目小于圖中的頂點數(shù),則表示圖中存在回路,算法結(jié)束,否則繼續(xù)執(zhí)行。

(2)從結(jié)束頂點Vn出發(fā),假設(shè)vl(n-1)?=?ve(n-1);然后求出各頂點i的最晚發(fā)生時間。

(3)根據(jù)頂點的最早發(fā)生時間,和最晚發(fā)生時間,依次求出出每條弧的最早開始時間和最晚開始時間,如果兩只相等,則為關(guān)鍵活動。關(guān)鍵活動組成的路徑則為關(guān)鍵路徑。

具體實現(xiàn)代碼:

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 #include <stdio.h> #define MAXVEX 100 /*首先聲明幾個全局變量*/ int?*etv,*ltv;??/*時間的最早發(fā)生時間和最遲發(fā)生時間*/ int?*stack2;??/*用于存儲拓撲序列的棧*/ int?top2;????/*用于stack2的指針*/ typedef?struct?EdgeNode???/*邊表節(jié)點*/ { int?adjvex;???????/*鄰接點域,存儲該頂點對應(yīng)的下表*/ int?weight;???????/*用于存儲權(quán)值,對于非網(wǎng)圖可以不需要*/ struct?EdgeNode *next;??/*鏈域,指向下一個鄰節(jié)點*/ }EdgeNode; typedef?struct?VertexNode???/*頂點表節(jié)點*/ { int?in;??????????/*頂點入度*/ int?data;???????/*頂點域,存儲頂點信心*/ EdgeNode *firstedge;?/*邊表頭指針*/ }VertexNode, Adjlist[MAXVEX]; typedef?struct { Adjlist adjList; int?numVertexes; int?numEdges;??/*圖中當前頂點數(shù)和邊數(shù)*/ }graphAdjList, *GraphAdjList; /*拓撲排序,若GL無回路,則輸出拓撲排序序列并返回OK,若有回路返回ERROR*/ int?TopoLogicalSort(GraphAdjList GL) { EdgeNode *e; int?i,k,gettop; int?top = 0;???/*用于棧指針下表*/ int?count = 0;?/*用于統(tǒng)計輸出頂點的個數(shù)*/ int?*stack;??/*建棧用于存儲入度為0的頂點*/ stack = (int*)malloc(GL->numVertexes *sizeof(int));??//動態(tài)分配內(nèi)存,大小為n個頂點(最多有n個頂點入度為0,因為圖總共有n個頂點) for(i = 0; i<GL->numVertexes; i++) if(GL->adjList[i].in == 0)??/*將入度為0的頂點入棧*/ stack[++top] = i; top2 = 0; etv = (int*)?malloc(GL->numVertexes*sizeof(int));??/*事件的最早發(fā)生時間*/ for(i=0;i<GL->numVertexes; i++) etv[i] = 0; stack2 = (int*)?malloc(GL->numVertexes*sizeof(int));?/*初始化*/ while(top != 0) { gettop = stack[top--];??/*出棧*/ printf("%d -> ",GL->adjList[gettop].data);?/*打印此頂點*/ stack2[++top2] = gettop;??/*將彈出的頂點序列號壓入拓撲序列的棧中*/ count++;?/*統(tǒng)計輸出頂點數(shù)*/ for(e=GL->adjList[gettop].firstedge; e; e=e->next) {?/*對此頂點弧表遍歷*/ k = e->adjvex; if(--GL->adjList[k].in == 0)??//將k號頂點鄰接點的入度減1,且減1后,入度為0的頂點需要存到棧中 stack[++top] = k; if((etv[gettop]+e->weight)>etv[k])?/*求各頂點時間最早發(fā)生時間*/ etv[k] = etv[gettop] + e->weight;??/*某個頂點的最早發(fā)生時間= 和他相關(guān)的活動必須全部完成*/ } } if(count < GL->numVertexes)??/*如果count小于頂點數(shù),說明存在環(huán)*/ return?-1; else return?0; } /*求關(guān)鍵路徑,GL為有向網(wǎng),輸出GL的各項關(guān)鍵活動*/ void?CriticalPath(GraphAdjList GL) { EdgeNode *e; int?i,gettop,k,j; int?ete,lte;????/*聲明活動最早發(fā)生時間和最遲發(fā)生時間*/ TopoLogicalSort(GL);??/*求拓撲序列,計算數(shù)組etv和stack2的值*/ ltv = (int*)?malloc(GL->numVertexes*sizeof(int));?/*時間的最晚發(fā)生時間*/ for(i= 0; i<GL->numVertexes;i++) ltv[i]=etv[GL->numVertexes-1];??/*初始化ltv[i] 為工程完成的最早時間,etv[i]初始化為0*/ while(top2!=0)??/*計算ltv*/ { gettop = stack2[top2--]; for(e=GL->adjList[gettop].firstedge;e!=NUll;e=e->next) {/*求各定點事件的最遲發(fā)生時間ltv值*/ k=e->adjvex; if(ltv[k]-e->weight<ltv[gettop]) ltv[gettop]= ltv[k]-e->weight;???/*求最晚發(fā)生時間,是從拓撲序列的最后一個頂點逆著推導(dǎo)*/ } } for(j=0;j<GL->numVertexes;j++)??/*求關(guān)鍵活動*/ { for(e=GL->adjList[j].firstedge;e!=NULL;e=e->next) { k=e->adjvex; ete = etv[j];???/*活動最早開始時間*/ lte = ltv[k] - e->weight;/*活動最晚發(fā)生時間*/ if(ete ==lte) printf("<v%d,v%d> length: %d, ",GL->adjList[j].data,GL->adjList[k].data,e->weight); } } }

總結(jié)

以上是生活随笔為你收集整理的拓扑排序--关键路径的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 色屁屁www| 激情欧美一区二区三区精品 | 五月天国产视频 | 久久网伊人 | a级在线观看 | 99久久久国产精品无码免费 | 久久久久久久久久久久久久av | 国产aⅴ爽av久久久久成人 | 撕开少妇裙子猛然进入 | 亚洲精品乱码久久久久久 | 日韩免费不卡视频 | 人妻无码一区二区三区 | 日本学生初尝黑人巨免费视频 | 蜜臀av无码一区二区三区 | 热久久亚洲 | 口爆吞精一区二区三区 | xxx老太太 | 91精品国产一区二区三区香蕉 | 国产伦精品一区二区三区免费迷 | 久久国产成人精品av | 日韩精品一线二线三线 | 免费午夜影院 | 少妇熟女一区二区三区 | 日本老太婆做爰视频 | www.色就是色 | 茄子视频懂你更多在线观看 | 亚洲免费不卡视频 | 美女扒开下面让男人捅 | 都市激情亚洲色图 | 婷婷精品 | 国产精品高潮呻吟久久av黑人 | 色乱码一区二区三区熟女 | 国产成人无码久久久精品天美传媒 | 亚洲色妞 | 天天插插 | 日本一区精品视频 | 亚洲图片欧美视频 | 欧美干 | 猎艳山村丰满少妇 | 艹少妇视频 | 久久香焦 | 国产福利免费视频 | 黄色三级在线视频 | 丁香婷婷九月 | 18男女无套免费视频 | 亚洲av无码国产精品久久不卡 | 免费av动漫 | 亚洲精品白浆高清久久久久久 | 天天碰天天摸 | 亚洲在线国产 | 久久亚洲AV无码 | 久久免费电影 | 浴室里强摁做开腿呻吟男男 | 亚洲精品天堂成人片av在线播放 | sm在线看 | 无码一区二区三区 | 日本人性爱视频 | 荒野求生21天去码版网站 | 污视频网站免费观看 | 日本一区二区在线 | 国产传媒在线播放 | 日韩精品你懂的 | 噼里啪啦国语版在线观看 | 国产av不卡一区二区 | 亚洲色图第一页 | 奇米影视亚洲 | 精品日韩 | av无遮挡 | 亚洲中文字幕一区在线 | 日韩精品www | 秋霞影院午夜丰满少妇在线视频 | 91视频看片 | 色综合婷婷 | 蜜臀av一区二区三区激情综合 | 欧美一区二区视频免费观看 | 亚洲综合丁香 | 日韩不卡高清视频 | 国产精品成人在线观看 | 欧美美女性生活 | 精品99在线观看 | 91人妻一区二区三区蜜臀 | 国产三级直播 | 国产精品乱码一区二三区小蝌蚪 | 婷婷久草| 欧美视频导航 | 中文字幕免费视频观看 | 亚洲理论电影在线观看 | 一级高清毛片 | 女人天堂网 | 日韩成人高清视频 | 久久不射电影网 | 欧美韩国日本在线 | 日本后进式猛烈xx00动态图 | 3o一40一50一6o女人毛片 | 日本一区二区三区精品视频 | 久久免费视频一区二区 | 欧美精品在线一区二区三区 | 色就操 | 久久综合婷婷国产二区高清 |