独立任务最优调度(双机调度)问题

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_26658823/article/details/78298957

    用两台处理机AABB处理nn个作业。设AABB处理第kk个作业的时间分别为aka_kbkb_k。由于各个作业的特点和机器性能的关系,对某些作业,在AA上的处理时间长;而对另一些作业,在BB上的处理时间更长。一台处理机在某个时刻只能处理一个作业,而且作业处理是不可中断的,每个作业只能被处理一次。现在要找出一个最优调度方案,使得nn个作业被这两台处理机处理完毕的时间和最少。

    本题是一个独立任务最优调度问题,也被称为双机调度问题,可以利用动态规划的思想解决。当完成kk个作业时,设机器AA花费了xx时间,机器BB花费时间的最小值肯定是xx的一个函数。设F[k,x]F[k, x]表示完成k个作业且机器AA花费xx时间的条件下机器BB所花费时间的最小值,那么F[k,x]=min{F[k1,x]+bk,F[k1,xak]}F[k, x] = min\{F[k-1, x] + b_k, F[k-1, x-a_k]\}。其中F[k1,x]+bkF[k-1, x] + b_k表示第k个作业由机器B来处理,完成前k1k-1个作业时机器AA所花费的时间还是xx。而F[k1,xak]F[k-1,x-a_k]表示第kk个作业由机器AA来处理,此时完成前k1k-1个作业机器A花费的时间是xakx-a_k

    根据FF的定义,我们知道F[n,x]F[n, x]表示完成nn个作业且机器AA花费xx时间的条件下机器BB所花费时间的最小值。显然,0xk=0nak0 \le x \le \sum\limits_{k = 0}^{n}a_k,所以对于xi(x_i(区间[0,k=0nak][0, \sum\limits_{k = 0}^{n}a_k]内的任一整数)),总有一个F[n,xi]F[n, x_i]与其对应,那么min{max{xi,F[n,xi]}}min\left\{max\{x_i, F[n, x_i]\}\right\}就是最后的结果。由于要处理每个作业kk,并且处理每个作业kk的时候都要循环j=0kaj\sum\limits_{j = 0}^{k}a_j次,所以算法的时间复杂度为O(nk=0nak)O(n\sum\limits_{k = 0}^{n}a_k)

    考虑以下包含66个作业的例子,其中ak={2,5,7,10,5,2}a_k=\{2,5,7,10,5,2\},而bk={3,8,4,11,3,4}b_k=\{3,8,4,11,3,4\}。下面对前两个作业进行简单的分析。

作业1 作业2 作业3 作业4 作业5 作业6
处理机A 2 5 7 10 5 2
处理机B 3 8 4 11 3 4

    对于第一个作业,机器$A$所花费时间$x$的取值范围是$0 \le x \le a_1$。当$x\lt0$时,设$F[1,x] = \infty$。$x=0$时,$F[1,0]=3$,此时$max(0,F[1,0])=3$,即机器$A$花费$0$时间,机器$B$花费$3$时间;$x=1$时,$F[1,1]=3$,$max(1,F[1,1])=3$;$x=2$时,$F[1,2]=0$,$max(2,F[1,2])=2$,此时作业$1$由机器$A$来处理,花费$2$时间,而机器$B$不处理作业。

    对于第二个作业,xx的取值范围是0xa1+a20 \le x \le a_1 + a_2。当x<0x\lt 0时,同样设F[2,x]=F[2,x] = \infty
    x=0x=0F[2,0]=min{F[1,0]+b2,F[1,0a2]}=min{3+8,}=11F[2,0]=min\{F[1,0]+b_2,F[1,0-a_2]\}=min\{3+8,\infty\}=11,所以max(0,11)=11max(0,11)=11
    x=1x=1F[2,1]=min{F[1,1]+b2,F[1,1a2]}=min{3+8,}=11F[2,1]=min\{F[1,1]+b_2,F[1,1-a_2]\}=min\{3+8,\infty\}=11,所以max(1,11)=11max(1,11)=11
    x=2x=2F[2,2]=min{F[1,2]+b2,F[1,2a2]}=min{0+8,}=8F[2,2]=min\{F[1,2]+b_2,F[1,2-a_2]\}=min\{0+8,\infty\}=8,所以max(2,8)=8max(2,8)=8
    x=3x=3F[2,3]=min{F[1,3]+b2,F[1,3a2]}=min{0+8,}=8F[2,3]=min\{F[1,3]+b_2,F[1,3-a_2]\}=min\{0+8,\infty\}=8,所以max(3,8)=8max(3,8)=8
    x=4x=4F[2,4]=min{F[1,4]+b2,F[1,4a2]}=min{0+8,}=8F[2,4]=min\{F[1,4]+b_2,F[1,4-a_2]\}=min\{0+8,\infty\}=8,所以max(4,8)=8max(4,8)=8
    x=5x=5F[2,5]=min{F[1,5]+b2,F[1,5a2]}=min{0+8,3}=3F[2,5]=min\{F[1,5]+b_2,F[1,5-a_2]\}=min\{0+8,3\}=3,所以max(5,3)=5max(5,3)=5
    x=6x=6F[2,6]=min{F[1,6]+b2,F[1,6a2]}=min{0+8,3}=3F[2,6]=min\{F[1,6]+b_2,F[1,6-a_2]\}=min\{0+8,3\}=3,所以max(6,3)=6max(6,3)=6
    x=7x=7F[2,7]=min{F[1,7]+b2,F[1,7a2]}=min{0+8,0}=0F[2,7]=min\{F[1,7]+b_2,F[1,7-a_2]\}=min\{0+8,0\}=0,所以max(7,0)=7max(7,0)=7
    根据上面的序列,我们可以知道当x=5x=5时,完成两个作业两台机器花费最少的时间为88,此时机器AA花费55时间,机器BB花费33时间。此外,还可以看出当x<a2x \lt a_2时,该任务必定由机器BB处理,因为数组下标小于00,是一个不合法的值。
    根据上述思路,编写代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#define MAXN 1005

int a[MAXN];//机器A处理各作业的时间
int b[MAXN];//机器B处理各作业的时间
int F[MAXN][MAXN];//
int time[MAXN];//处理作业k所需要的最短时间
int n;

void read() {
    printf("请输入作业数量:");
    scanf("%d",&n);
    printf("请输入机器A处理每个作业的时间:");
    for(int i = 1; i <= n; i++) {
        scanf("%d",&a[i]);
    }
    printf("请输入机器B处理每个作业的时间:");
    for(int i = 1; i <= n; i++) {
        scanf("%d",&b[i]);
    }
}

int min(int x, int y) {
    return x < y ? x : y;
}

int max(int x, int y) {
    return x > y ? x : y;
}

int schedule() {
    int sumA = a[1];
    //k = 1的情况
    for(int x = 0; x < a[1]; x++) {
        F[1][x] = b[1];
    }
    F[1][a[1]] = min(b[1],a[1]);
    //初始化
    for(int i = 2; i <= n; i++) {
        for(int j = 0; j <= n; j++) {
            F[i][j] = INT_MAX;
        }
    }
	//k >= 2的情况
    for(int k = 2; k <= n; k++) {
        sumA += a[k];
        time[k] = INT_MAX;
        for(int x = 0; x <= sumA; x++) {
            if(x < a[k]) {
                F[k][x] = F[k-1][x] + b[k];
            } else {
                F[k][x] = min(F[k-1][x] + b[k], F[k-1][x-a[k]]);
            }
            time[k] = min(time[k],max(x,F[k][x]));
        }
    }
    return time[n];
}

int main(void) {
    read();
    printf("总的最少处理时间为:%d\n",schedule());
    return 0;
}

    运行结果如下:
这里写图片描述

展开阅读全文

没有更多推荐了,返回首页