美文网首页
关键路径

关键路径

作者: 小幸运Q | 来源:发表于2018-07-09 19:53 被阅读1次

定义:

AOE网的最长路径,决定了整个工程的工期。如果有正环的话则不存在。(最早开始时间和最晚开始时间相等,一刻都不能等)


image.png

编码解决问题:

ve[i]表示i节点(事件)的最早发生时间,vl[i]表示i节点(事件)的最晚发生时间。
对事件ar来说,e[r]=ve[i],即事件ar的最早发生时间是i事件的最早发生时间。
事件ar的最晚发生时间 l[r]=vl[j]-length[r]

ve数组求解过程:最早结束时间+length后最晚(大)的那个值

最早可以什么时候开始?

有k个事件Vi1-Vik到达Vj,取max{ve[ip]+length[ar]}=ve[j],使用拓扑排序保证Vi1-Vik的ve值已被求解出来。

image.png

vl数组求解过程:后面节点中最晚发生的时间-length后最小的那个值(默认vl[n]=ve[n])

最晚可以什么时候开始?

image.png

完整过程:

Ve(最早)是从左往右遍历,Vl(最晚)是从右往左遍历。然后求每条弧的最早开工时间和最迟开工时间(其实是求每个点)是否相等,若相等,则是关键活动。

Ve是从左往右遍历,因为Ve是多对一的情况,所以先对队列中degree为0的元素进行拓扑排序式遍历,计算degree为0的点A的所有领点然后取max(ve[nextpoint],ve[A]+(A->nextpoint的length))覆盖ve[nextpoint],边遍历degree==0的点边将点push进栈,为Vl的遍历做准备。
Vl在Ve栈的基础上逆向回退,实现1对多的Vl遍历。取min(vl[A],vl[nextpoint]-(A->nextpoint的length)),在遍历前吧所有的Vl设为ve[maxn],防止初始值为0对答案的干扰。

image.png

测试数据:

image.png
10 14
1 2 3
1 3 5
1 4 10
2 5 10
3 6 4
4 6 9
5 7 2
6 7 3
6 8 20
6 9 4
9 8 1
7 10 7
8 10 10
9 10 4

示例代码:

degree[N]={0};
bool occupy[N]={false};
typedef struct{
  int num;
  int length;
  int l;
  int e;
}Node;
vector<vector<Node>>v;
#include <bits/stdc++.h>
using namespace std;
#define N 10000
int points,edges;
typedef struct{
  int num;
  int length;
  int l;
  int e;
}Node;
vector<vector<Node>>v;
bool occupy[N]={false};
int degree[N]={0};
// 最早ve和最晚vl
int ve[N]={0};
int vl[N]={0};

void mainpath(vector<vector<Node>>&v){
  vector<int>path;
  queue<int>p;
  int i,j;
  int mainlength=0;
  for(i=1;i<points+1;i++){
    if(degree[i]==0&&occupy[i]==false){
      occupy[i]=true;
      p.push(i);
    }
  }
  while(!p.empty()){
    int num=p.front();
    p.pop();
    path.push_back(num);
    //将路径写入path中

    // 从左往右选择最大的ve
    for(i=0;i<v[num].size();i++){
      int choosed=v[num][i].num;
      degree[choosed]--;
      // 修改ve[choosed]=ve[num]+mainlength
      ve[choosed]=max(ve[choosed],ve[num]+v[num][i].length);
      if(degree[choosed]==0){
        p.push(choosed);
        occupy[choosed]=true;
      }
    }
  }
  for(i=1;i<points+1;i++){
    vl[i]=ve[points];
    // 把所有vl设置为ve的最大值,最后一个ve。
  }

  int  times=path.size();
  // 把vector当作栈,从后往前遍历修改vl
  for(i=0;i<times;i++){
    int num=path.back();
    // pop节点
    path.pop_back();
    if(!v[num].empty()){
      // 对节点之后的节点vl[t]-length与v[num]比较,如果更小则替换v[num]。
      for(j=0;j<v[num].size();j++){
          int t=v[num][j].num;
          if(vl[num]>vl[t]-v[num][j].length){
            vl[num]=vl[t]-v[num][j].length;
          }
      }
    }
  }
  cout<<"-----------"<<endl;
  // 如果点A的ve==vl,则说明该点位于关键路径上。
  // 从start开始往下遍历
  int start=1;
  // 如果没有后继节点则停止
  while(!v[start].empty()){
    for(j=0;j<v[start].size();j++){
      if(ve[v[start][j].num]==vl[v[start][j].num]){
        cout<<start<<"->"<<v[start][j].num<<endl;
        mainlength+=v[start][j].length;
        start=v[start][j].num;
        break;
      }
    }
  }
  cout<<"Main length:"<<mainlength<<endl;
}
// 检查是否有重边。
bool check(vector<vector<Node>>&v,int point1,int point2){
  int i,j;
  for(i=0;i<v[point1].size();i++){
    if(v[point1][i].num==point2){
      return false;
    }
  }
  return true;
}
int main(){
  int i,j;
  scanf("%d %d",&points,&edges);
  for(i=1;i<points+1;i++){
    vector<Node>vv;
    v.push_back(vv);
  }
  int point1,point2,length;
  Node node;
  for(i=0;i<edges;i++){
    scanf("%d %d %d",&point1,&point2,&length);
    if(check(v,point1,point2)){
      node.num=point2;
      node.length=length;
      v[point1].push_back(node);
      degree[point2]++;
    }
  }
  mainpath(v);
}


10 14
1 2 3
1 3 5
1 4 10
2 5 10
3 6 4
4 6 9
5 7 2
6 7 3
6 8 20
6 9 4
9 8 1
7 10 7
8 10 10
9 10 4

相关文章

  • 7. 关键路径

    关键路径 : 从源点到汇点的所有路径中,具有最大路径长度的路径称为关键路径 关键路径代表 : 1) 图中最长路径;...

  • 关键路径

    #include #include #include #include us...

  • 关键路径

    定义: AOE网的最长路径,决定了整个工程的工期。如果有正环的话则不存在。(最早开始时间和最晚开始时间相等,一刻都...

  • 关键路径

    顶点v有的特征是ve和vl 边有的特征是e和l ve就是从开始结点到顶点v的最大路径长度 vl就是允许事件最晚的发...

  • 关键路径

    在网络图中的某些活动可以并行地进行,所以完成工程的最少时间是从开始顶点到结束顶点的最长路径长度,从开始顶点到结束顶...

  • 关键路径

    AOE网 在一个表示工程的带权有向图中,用顶点表示事件,用有向边表示活动,用边上的权值表示活动的持续时间,这种有向...

  • 关键路径

    关键路径: 拓扑排序主要是解决一个工程能否顺序进行的问题,但是有时候还需要解决工程完成需要的最短时间问题。在前面介...

  • 关键路径法

    关键路径法 关键路径是指设计中从输入到输出经过的延时最长的逻辑路径。优化关键路径是一种提高设计工作速度的有效方法。...

  • 图的关键路径

    关键路径:在AOV网中,路径上各个活动所持续的时间之和称为路径长度,从源点到汇点具有最大长度的路径叫做关键路径。 ...

  • 06:项目管理进度19

    关键路径法CPM(P210)关键路径。次关键路径。如何用7格图顺推逆推计算活动的日期属性7格图计算活动的日期---...

网友评论

      本文标题:关键路径

      本文链接:https://www.haomeiwen.com/subject/enozuftx.html