【关键路径问题(代码以及细节)】

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

本代码可以求任意两点的关键路径:

#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;

    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];


    int res = i;

    //工期的长度

    int sum = 0;

    for (i = 0; path[i] != last; i++)

    {

        if (i != res)

            sum += d[path[i]][path[i + 1]];

    }

    cout << endl

         << "总工期为" << sum << endl;

}


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);

        }

    }

}

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);

        }

    }

}

结果:

工序完成所需时间:

虽然是要求五个未知量,但其实求出两个就可以:每个工序对应的EF=ES+ 权值;②每个工序对应的LF=LS+ 权值;故只用求ES,LS就行;

SL=LF-EF(或者LS-ES);当然,还有一个重要的量要求,即每个活动的最早完成时间,因为LS是在知道每个活动(数字①.②...)的最早完成时间后从后往前推的;(每个活动的最早完成时间即ES(①..②...⑧)应该大家都会,这里不做过多解释,说一点就是,如果某个工序有多条路径,需要留下最大的权值)

然后对于每个工序的LS:

比如LS(l)=ES(8)-L的权值=25-8=17,以此类推;

 有同学不会从表格中看关键路径?其实很简单,只需要看SL,当缓冲时间为0时,即为关键路径如此题:1—>8的关键路径为:B. D. E. J. L,   你学会了吗?

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值