C++实现离散数学中关键路径

一、实验目的

掌握AOE网以及关键路径在工程实践中的应用。

二、实验内容

假定你是某食品加工公司生产线调试负责人,现在要新增一条食品生产线,涉及12个工序(活动),工序之间的关系及完成所需时间见项目网络图1和表1,请应用项目网络图的方法,尝试推导出该食品生产线的关键工序(关键路径)及项目工期,并编程实现。

 

 

(1)求各工序(活动)的最早开始时间ES、最早完成时间EF、最晚开始时间LS、最晚完成时间LF,并将表1中的数据项补充完整。

提示:先计算每个事项(即顶点)的最早开始时间ES(i)和最晚完成时间LF(i)(i=1,2,...,8),利用公式ES(i,j)=ES(i),EF(i,j)=ES(i)+wij 。其中(i,j)表示工序,wij 表示完成工序(i,j)所需要的时间。

LF(i,j)=LF(j),LS(i,j)=LF(j)-wij。其中(i,j)表示工序,wij 表示完成工序(i,j)所需要的时间。SL(i,j)= LS(i,j)-ES(i,j),工序(i,j)的缓冲时间= LS(i,j)-ES(i,j)。

(2)求关键路径、关键工序及项目的工期。

要求:请利用离散数学的关键路径理论知识储备,自行解决上述问题,补充上述表格,并根据上述表格结果推导出关键路径和工序及工期。

三、程序设计流程图(或实验原理)

(1)工序完成所需时间

工序

A

B

C

D

E

F

G

H

I

J

K

L

紧前工序

-

-

-

B

A,D

B

B

C

C

E,F

G,H

I,J

时间(天)

1

3

3

6

5

4

3

2

2

3

2

8

ES

0

0

0

3

9

3

3

3

3

14

6

17

EF

1

3

3

9

14

7

6

5

5

17

8

25

LS

8

0

12

3

9

10

20

21

15

14

23

17

LF

9

3

15

9

14

14

23

23

17

17

25

25

SL

8

0

12

0

0

7

17

18

12

0

17

0

四、实验内容(或实验步骤)

关键路径、关键工序及项目的工期

事项的最早开始时间 :

ES(1)=0;

ES(2)=max{0+1,0+3+6}=9;

ES(3)=max{0+3}= 3;

ES(4)=max{0+4}= 4;

ES(5)=max{1+5,3+6+5,3+4}= 14;

ES(6)=max{3+3,3+2}= 6;

ES(7)=max{3+2,1+5+3,3+6+5+3,3+4+3}=17;

ES(8)=max{3+2+8,1+5+3+8,3+6+5+3+8,3+4+3+8}=25;

事项的最晚开始时间 :

LF(v8)=25;

LF(v7)=min{25-8}=17

LF(v6)=min{25-2}=23

LF(v5)=min{17-3}=14

LF(v4)=min{17-2,23-2}=15

LF(v3)=min{14-4,23-3,9-6}=3

LF(v2)=min{14-5}=9

LF(v1)=min{3-3,9-1,15-3}=0

项目总工期为:25天,相关时间活动列于表(1)中,关键活动是:B,D,E,J,L

关键路径:1-3-2-5-7-8

五、实验小结(实验结果、存在的问题及解决的方法等

演示:

 

关键路径代码:

#include <iostream>
using namespace std;
#define max 1000000
int d[10][10];
int earliest[10];
int latest[10];
int path[10];
void findEarliest(int k, int last);
void findLatest(int k, int first);
bool flag = false; //用于判断是否存在关键路径

int main()
{
    int i, j, k, m, n = 10;
    int u, v, w;
    int first, last, count = 0;
    int next;
    cout << "请输入边数:";
    cin >> m;

    for (i = 0; i < m; i++)
    {
        for (j = 0; j < m; j++)
            d[i][j] = max;
    }
    cout << "请输入每条边的顶点及其权重" << endl;
    for (i = 0; i < m; i++)
    {
        cin >> u >> v >> w;
        d[u][v] = w;
    }
    cout << "请输入要查询的两点:";
    cin >> first >> last;

    for (i = 0; i < 10; i++)
    {
        earliest[i] = 0;
        latest[i] = max;
        path[i] = max;
    }

    k = first;
    path[0] = k;
    count = 1;
    findEarliest(k, last);
    if (!flag)
    {
        cout << "路径不存在";
        return 0;
    }

    k = last;
    latest[k] = earliest[k];
    findLatest(k, first);

    k = first;
    while (k != last)
    {
        for (i = 0; i < 10; i++)
        {
            if (d[k][i] != max && (latest[i] - d[k][i] == earliest[k]))
            {
                path[count++] = i;
                k = i;
                break;
            }
        }
    }
    cout << "关键路径为:" << endl;
    for (i = 0; path[i] != last; i++)
    {
        cout << path[i] << "->";
    }
    cout << path[i];
}

void findEarliest(int k, int last)
{
    if (k == last)
        return;
    flag = false;
    for (int i = 0; i < 10; i++)
    {
        if (d[k][i] < max)
        {
            flag = true;
            if ((earliest[k] + d[k][i]) > earliest[i])
                earliest[i] = earliest[k] + d[k][i];
            findEarliest(i, last);
        }
    }
    //如果flag没有在循环中被修改为ture,则说明没有节点与k相连(即没有进入if语句内,函数返回不再进行递归),然后在主函数中判断flag的值来决定是否继续
}
void findLatest(int k, int first)
{
    if (k == first)
        return;
    for (int i = 0; i < 10; i++)
    {
        if (d[i][k] < max)
        {
            if (latest[k] - d[i][k] < latest[i])
                latest[i] = latest[k] - d[i][k];
            findLatest(i, first);
        }
    }
}

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LCH南安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值