动态规划-流水作业调动Johnson法则

//问题分析:
// 1.作业合集N={1,2,3…n},//S属于N;M1上不停止的工作,
// 因此M1加工S中的作业时,M2还在加工N-S中的某作业,
// 需要等时间t后才能利用M2.
// 2.这种情况下,完成S作业的最短时间记为T( S,t);//t为安排{N-S}后面的等待时间
// 流水作业调度问题的最优值为T(N,0);//M2无需等待的情况
// 3.对于n个作业,其最优调度为Π,时间为aΠ(1)+T’;
// T’为M2的等待时间为bΠ(1)时,作业aΠ(2,。。。。n)的最优时间
//则T’=T(n-Π(1),bΠ(1));
//可以理解为T是大问题安排的时间,T‘是小问题安排的时间;
//4.最优子结构问题:T(N,o)=min{ai+T(N-i,bi)};------子结构问题,对于N个问题中的每个问题进行调度,
// 将问题规模缩小,求最短的结果作为选择方案
//
//T(S,t)=min{ai+T(S-i,bi+max{t-ai,0})};-------在M2上的等待时间为bi+{t(M2上{N-S}后面的等待时间)-ai(M1上的工作时间)}
//(冲抵了,t是从ai开始工作,M2所等待的时间)
//如果t>ai,那么安排a1后,安排别的工作M2等待的时间就为t-ai,;
//如果t<=ai,那么,安排a1后,安排别的工作M2等待的时间就为0;

图片来源:https://www.cnblogs.com/f91og/p/6024706.html

#include <iostream>
#include<string>
#include<algorithm>
using namespace std;
#define N 6
struct node {
    int time;//执行时间
    int index;//作业序号
    bool group;//机器1、2
};
bool cmp(node a, node b)//升序
{
    return a.time < b.time;//a小则true
}

int main()
{
    int a[N] = { 2,7,6,4,6,8 }, b[N] = {5,3,2,7,9,2};
    node *c=new node [N];
    int best[N];//最优调度顺序
    for (int i = 0; i < N; i++)
    {
        c[i].index = i;
        c[i].time = a[i] > b[i] ? b[i] : a[i];//赋值小的
        c[i].group = a[i] <= b[i];//作业i在M1上时间小则true
    }


    //排序
    sort(c, c + N, cmp);//c[]作业时间升序

    int j = 0, k = N - 1;
    //a小前,b小后面
    for (int i = 0; i < N; i++)
    {
        if (c[i].group) {
            //a[i]小
            best[j++] = c[i].index;
        }
        else {
            best[k--] = c[i].index;//b[i]大的放在后面
        }
    }

    //
    j = a[best[0]];//第一个作业在M1上的时间
    k = j + b[best[0]];//第一个作业在M2上的时间+M1上的时间
    for (int i = 1; i < N; i++)
    {
        j += a[best[i]];//按最优调度的顺序下a[]累计时间总和
        k = j<k?(k+b[best[i]]):j+b[best[i]];//
        //1.best[1..+..i]<a[best0]+b[best0];k=a[best0]+b[best0]+b[best1....];
        //2 .        >=       ;k=a{best0...i]+b[besti+1...];
    }
    cout << k<<endl;//消耗时间最大值
    for (int i = 0; i < N; i++)//序号输出
    {   
        cout << best[i] + 1 << ' ';
    }
    cout << endl;
    return 0;
   
}

代码思路来源,非常详细!!!!!!
https://blog.csdn.net/qq_44766883/article/details/106211941

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值