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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

aoe网最早开始时间和最迟开始时间_关键路径(AOE)网 通俗易懂

發布時間:2024/1/23 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 aoe网最早开始时间和最迟开始时间_关键路径(AOE)网 通俗易懂 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

關鍵路徑

關鍵路徑是求「工程上時間最短的問題」的方法
閱讀本文前請先了解
拓撲排序

拓撲排序主要解決「工程是否能順序進行」的問題,關鍵路徑在拓撲排序的基礎上解決「工程最短時間的問題」。

一、工程最短時間

工程時間最短的問題:

按照工廠上圖生產一輛汽車,外殼、發動機、輪子和其他部件可以同時建造。
(1)求組裝完成最短需要多少時間?
(2)如何縮短最短時間?
答案:
(1)
因為所有部件可以同時建造,所以只要最長時間的「發動機」不建造完畢集中部件就無法進行。所以:「工程最短時間」就是通向匯點的和 最長的權重。(最長權重的路徑也叫做「關鍵路徑」)
上圖 開始 -> 發動機完成 -> 部件集中完成 -> 組裝完成 就是最長權重,組裝完成最短用時 6
(2)
關鍵路徑性質:縮短關鍵路徑上的時間就能縮短最短時間(但是縮短的同時關鍵路徑會動態發生變化,比如發動機建造時間 <= 2 ,繼續縮短發動機建造時間就沒用了)

二、AOE (Activity On Edge)網絡

找出最長權重的路徑就是關鍵路徑。所以邊必須有權重。(沒權重咋算??)

我們要在「拓撲排序」AOV 網的基礎上介紹 AOE 網,區別如下

  • AOV(Activity On Vertex):活動在頂點上,邊沒有權重
  • AOE(Activity On Edge):活動在邊上,邊有權重

定義如下:

  • 邊(Edge)稱之為「活動」(比如造輪子)
  • 頂點(Vertex)稱之為「事件」(比如說輪子完成)

三、關鍵路基算法

3.1 關鍵路徑算法原理

我們如何求出關鍵路徑?

我們舉個例子:
小明有 2 個小時的作業,回家一共有 4 個小時做作業的時間。他可以選擇一開始就做,或者因為「ddl 綜合征」最后 2 小時才開始做。此時「做作業最早的時間」和「做作業的最晚時間」是不等的。
老師知道小明的情況后將小明的作業增加到了 4 個小時的量,小明做作業的時間還是 4 個小時。小明只能回家就開始做作業才能做完。此時「做作業最早的時間」和「做作業的最晚時間」是相等的。
「做作業最早的時間」和「做作業的最晚時間」是相等的說明:如果做作業的時間延誤,將會導致整個工期延誤,做作業的時間縮短,整個工期的最短時間就會縮短。
我們將「做作業」抽象為「活動」Activity,「作業完成」抽象為「事件」Event
關鍵路徑定義:活動的最早發生時間和最晚發生時間相等的路徑就是關鍵路徑

求關鍵路徑我們只需要求出「活動最早發生時間」和「活動最晚發生時間」即可。

3.2 關鍵路徑算法

(1)參數定義

求關鍵路徑我們只需要求出「活動最早發生時間」和「活動最晚發生時間」即可。

但是在 AOE 圖中,「活動」就是向量邊,求向量邊一般是困難的,我們可以借助頂點來求邊。

參數定義如下:

  • etv(Earliest Time of Vertex):頂點最早發生時間,也就是「事件最早發生時間」
  • ltv(Lastest Time of Vertex):頂點最晚發生時間,也就是「事件最晚發生時間」
  • ete(Earliest Time of Edge):邊最早發生時間,也就是「活動最早發生時間」
  • lte(Lastest Time of Edge):邊最晚發生時間,也就是「活動最晚發生時間」

我們通過 etv 求 ete,ltv 求 lte

(2)算法步驟

步驟如下:(結合代碼理解)

  • 通過拓撲排序求出 etv「事件最早發生時間」

etv[j] = max{etv(i) + weight}

  • 通過「反向推導」求出 ltv「事件最晚發生時間」

ltv[i] = max{etv(j) - weight}

  • 通過 etv 求出 ete「活動最早發生時間」

活動最早發生時間等于 from(箭頭開始方向的事件最早發動時間)

  • 通過 ltv 求出 lte「活動最晚發生時間」

活動最晚發生時間等于 to - weight(箭頭結束方向的事件發生時間 - 權重)

  • 通過 lte - ete 求出關鍵路徑

四、代碼

示例如下圖:

public class CriticalPath {/** 邊 */static class Edge{/** 權重 */int weight;/** 出度指向的點 */int toVertex;Edge next;public Edge(int weight, int toVertex, Edge next) {this.weight = weight;this.toVertex = toVertex;this.next = next;}}/** 頂點 */static class Vertex{/** 入度 數量 */int inNumber;/** 頂點信息 */Integer data;/** 第一條邊 */Edge firstEdge;public Vertex(int inNumber, Integer data, Edge firstEdge) {this.inNumber = inNumber;this.data = data;this.firstEdge = firstEdge;}}static void criticalPath(List<Vertex> graph){//頂點數量int length = graph.size();//邊數量int numOfEdges = 0;for (Vertex vertex : graph) {Edge edge = vertex.firstEdge;while (edge!=null){numOfEdges ++;edge = edge.next;}}//事件最早發生時間int[] etv = new int[length];//事件最晚發生時間int[] ltv = new int[length];//活動最早發生時間int[] ete = new int[numOfEdges];//活動最晚發生時間int[] lte = new int[numOfEdges];//1. 通過拓撲排序求 etv 「事件最早發生時間」//etvStack 用于儲存拓撲排序后的順序Stack<Vertex> etvStack = new Stack<>();//stack 用于拓撲排序Stack<Vertex> stack = new Stack<>();for (Vertex vertex : graph) {if (vertex.inNumber == 0){stack.push(vertex);}}while (!stack.isEmpty()){Vertex pop = stack.pop();//儲存拓撲排序后的結構etvStack.push(pop);//遍歷出度Edge edge = pop.firstEdge;while (edge != null){Vertex vertex = graph.get(edge.toVertex);vertex.inNumber --;if (vertex.inNumber == 0){stack.push(vertex);}//賦值更大的距離給 etvif (etv[pop.data] + edge.weight > etv[edge.toVertex]){etv[edge.toVertex] = etv[pop.data] + edge.weight;}edge = edge.next;}}//2.通過 etv 反向推導求出 ltv「事件最晚發生時間」System.out.println("====etv====");for (int i = 0; i < etv.length; i++) {System.out.print("V"+i +" = "+etv[i]+" ");}System.out.println();//初始化 ltvInteger endVertex = etvStack.peek().data;for (int i = 0; i < ltv.length; i++) {ltv[i] = etv[endVertex];}while (!etvStack.isEmpty()) {Vertex pop = etvStack.pop();Edge edge = pop.firstEdge;while (edge != null) {//賦值更小的距離給 ltvif (ltv[pop.data] > ltv[edge.toVertex] - edge.weight) {ltv[pop.data] = ltv[edge.toVertex] - edge.weight;}edge = edge.next;}}System.out.println("====ltv====");for (int i = 0; i < ltv.length; i++) {System.out.print("V"+i +" = "+ltv[i]+" ");}System.out.println();//3. 通過 etv 求 eteint index = 0;for (Vertex vertex : graph) {Edge edge = vertex.firstEdge;while (edge != null){ete[index++] = etv[vertex.data];edge = edge.next;}}System.out.println("====ete====");for (int i = 0; i < ete.length; i++) {System.out.print("E"+i +" = "+ete[i]+" ");}System.out.println();//4. 通過 ltv 求 lteindex = 0;for (Vertex vertex : graph) {Edge edge = vertex.firstEdge;while (edge != null){lte[index++] = ltv[edge.toVertex] - edge.weight;edge = edge.next;}}System.out.println("====lte====");for (int i = 0; i < lte.length; i++) {System.out.print("E"+i +" = "+lte[i]+" ");}System.out.println();//5. 用 lte - ete 求關鍵路徑 System.out.println("====關鍵路徑====");for (int i = 0; i < ete.length; i++) {if (lte[i] - ete[i] == 0) {System.out.print("E"+i+" ");}}return ;}/** 測試 */public static void main(String[] args) {char[] vertices = new char[]{'A','B','C','D','E','F','G'};Edge e3 = new Edge(2, 4, null);Edge e2 = new Edge(1, 3, e3);Edge e1 = new Edge(3, 2, e2);Edge e0 = new Edge(2, 1, e1);Edge e4 = new Edge(1, 5, null);Edge e5 = new Edge(1, 5, null);Edge e6 = new Edge(1, 5, null);Edge e7 = new Edge(1, 5, null);Edge e8 = new Edge(2, 6, null);Vertex a = new Vertex(0, 0, e0);Vertex b = new Vertex(1, 1, e4);Vertex c = new Vertex(1, 2, e5);Vertex d = new Vertex(1, 3, e6);Vertex e = new Vertex(1, 4, e7);Vertex f = new Vertex(4, 5, e8);Vertex g = new Vertex(1, 6, null);ArrayList<Vertex> graph = new ArrayList<>();graph.add(a);graph.add(b);graph.add(c);graph.add(d);graph.add(e);graph.add(f);graph.add(g);criticalPath(graph);} }

結果:

====etv==== V0 = 0 V1 = 2 V2 = 3 V3 = 1 V4 = 2 V5 = 4 V6 = 6 ====ltv==== V0 = 0 V1 = 3 V2 = 3 V3 = 3 V4 = 3 V5 = 4 V6 = 6 ====ete==== E0 = 0 E1 = 0 E2 = 0 E3 = 0 E4 = 2 E5 = 3 E6 = 1 E7 = 2 E8 = 4 ====lte==== E0 = 1 E1 = 0 E2 = 2 E3 = 1 E4 = 3 E5 = 3 E6 = 3 E7 = 3 E8 = 4 ====關鍵路徑==== E1 E5 E8

總結

以上是生活随笔為你收集整理的aoe网最早开始时间和最迟开始时间_关键路径(AOE)网 通俗易懂的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。