加工生产调度

某工厂收到了n个产品的订单,这n个产品分别在A、B两个车间加工,并且必须先在A车间加工后才可以到B车间加工。
某个产品i在A、B两车间加工的时间分别为Ai、Bi。怎样安排这n个产品的加工顺序,才能使总的加工时间最短。这里所说的加工时间是指:从开始加工第一个产品到最后所有的产品都已在A、B两车间加工完毕的时间。
第一行仅—个数据n(0<n<1000),表示产品的数量。
接下来n个数据是表示这n个产品在A车间加工各自所要的时间(都是整数)。
最后的n个数据是表示这n个产品在B车间加工各自所要的时间(都是整数)。
第一行一个数据,表示最少的加工时间;
样例输入 Sample Input
5
3 5 8 7 10
6 2 1 4 9
样例输出 Sample Output
34
数据范围及提示 Data Size & Hint
0<n<1000

 

题目解析:
本题是要求一个加工顺序使得总的加工时间最少,而要使加工时间最少,就是让各车间的空闲时间最少。一旦A车间开始加工,便会不停地进行加工(我们不要去管车间是否能够一直生产,因为他们有三班,可以24时间不停地运转)。关键是B车间在生产的过程中,有可能要等待A车间的初加工产品。很显然所安排的第一个产品在A车间加工时,B车间是要等待的,最后一个产品在B车间加工时,A车间已经完成了任务。
要使总的空闲时间最少:
(1)就要把在A车间加工时间最短的部件优先加工,这样使得B车间能以最快的速度开始加工;
(2)把放在B车间加工时间最短的产品放在最后加工,这样使得最后A车间的空闲时间最少。
设计出这样的贪心法:
设Mi=min{Ai,Bi}
将M按照由小到大的顺序排序,然后从第一个开始处理,如果Mi=Ai,则将它安排在从头开始的已经安排的生产顺序后面,如果Mi=Bi,则将它安排在从尾开始的已安排的生产顺序前面。
这种安排是否是最少的加工时间,还要通过数学证明。证明如下:
(请学生自行证明完成!)
特殊案例分析:
(1)考虑Ai=Bi的任务的高度情况怎样为最优方案。
(2)考虑Ai<=Bi的任务的调度情况怎样为最优方案。
提出、分析、证明。
(概念1:最大缓冲区域)

设S=<J1,J2,…,Jn),是等待加工的作业序列,如果A车间开始加工S中的产品时,B车间还在加工其他产品,t时刻后B车间就可利用A车间加工过的产品。在这样的条件下,加工S中任务所要的最短时间T(S, t)=min{Ai+T(s-{Ji},Bi+max{t-Ai, 0})},其中,Ji∈S。
图3-1是加工作业i时A车间等待B车间的情况:

图3-1 A等B的情况
图3-2是加工作业i时B车间等待A车间的情形:

图3-2 B等A的情况
假设最佳的方案中,先加工作业Ji,然后再加工作业Jj,则有:


如果 ,则
如果 ,则
如果 ,则
如果将作业Ji和作业Jj的加工顺序调整,则有:

其中,
按照上面的假设,有T<=T’,所以有:

从而有:

即:
这说是所谓的Johnson公式,也就是说在此公式成立的条件下,优先安排任务Ji在Jj之前可以得到最优解。也就是在A车间加工时间短的安排在前面,在B车间加工时间短的任务安排在后面。
以样例数据为例:
(A1, A2, A3, A4, A5)=(3, 5, 8, 7, 10)
(B1, B2, B3, B4, B5)=(6, 2, 1, 4, 9)
则(m1, m2, m3, m4, m5)=(3, 2, 1, 4, 9)
排序之后为:(m3, m2, m1, m4, m5)
处理m3,因为m3=B3,所以m3安排在后面(,,,,3);
处理m2,因为m2=B2,所以m2安排在后面(,,,2,3);
处理m1,因为m1=A1,所以m1安排在前面(1,,,2,3);
处理m4,因为m4=B4,所以m4安排在后面(1,,4,2,3);
处理m5,因为m5=B5,所以m5安排在后面(1,5,4,2,3)。
从而得到加工的顺序1,5,4,2,3。计算出最短的加工时间34。
【补充说明】
由于本题的原始数据并没有保证数据间没有重复,所以在数据有重复的情况下生产调度安排并不是惟一的。但是最少的加工时间是惟一的。

思考2:任务j(如果aj=bj)在A车间的加工时间与其在B车间的加工时间相同的话,任务j的加工处理在任何时侯处理都相同,也就是说加工过程中如果我们在最优方案基础上,仅仅是调整任务j的加工顺序,则将得到一个等效的加工方案。
证明:
在已知的最优方案中,如果有任务i,并且Ai=Bi,则如果改变其加工顺序。我们将得到一个等效的最优加工方案。
(根据以上特征,为了让输出解达到唯一,我们只有进而求其次,我在测试数据中修改了一下,将所有的测试数据均改为Ai<>Bi)

 

 

 

program prod;
type
    data=record
        num,tima,timb,min:integer;
    end;
    arr=array[1..1000]of data;
var
    a,b:arr;
    n,i,j,k:integer;
    sa,sb:longint;

procedure qsort(var a:arr; l,r:integer);
var
    i,j,m:integer;
    t:data;
begin
    i:=l; j:=r; m:=a[(i+j)div 2].min;
    repeat
        while a[i].min<m do inc(i);
        while m<a[j].min do dec(j);
        if i<=j then
        begin
            t:=a[i]; a[i]:=a[j]; a[j]:=t;
            inc(i);
            dec(j);
        end;
    until i>j;
    if l<j then qsort(a,l,j);
    if i<r then qsort(a,i,r);
end;

begin
    readln(n);
    sa:=0;
    for i:=1 to n do
    begin
        read(a[i].tima);
        inc(sa,a[i].tima);
        a[i].num:=i;
        a[i].min:=a[i].tima; 
    end;
    for i:=1 to n do
    begin 
        read(a[i].timb);
        if a[i].timb<a[i].min then a[i].min:=a[i].timb; 
    end;
    qsort(a,1,n);
    i:=1; j:=n;
    for k:=1 to n do
        if a[k].min=a[k].tima then begin b[i]:=a[k];inc(i); end
        else begin b[j]:=a[k]; dec(j); end;
    i:=1; j:=0;
    sa:=b[1].tima; sb:=b[1].tima;
    repeat
        inc(i); inc(j);
        if (sa+b[i].tima)>=(sb+b[j].timb) then
        begin
            inc(sa,b[i].tima);
            sb:=sa; 
        end
        else
        begin
            inc(sa,b[i].tima);
            inc(sb,b[j].timb);
        end;
    until (i=n)and(j=n-1);
    inc(sb,b[n].timb);
    writeln(sb);
    write(b[1].num);
    for i:=2 to n do write(' ',b[i].num);
    writeln;
end.

 

posted @ 2015-11-19 10:23  qilinart  阅读(948)  评论(0)    收藏  举报