例4.13 职员时序安排模型
一项工作一周7天都需要有人(比如护士工作),每天(周一至周日)所需的最少职员数为20、16、13、16、19、14和12,并要求每个职员一周连续工作5天,试求每周所需最少职员数,并给出安排。注意这里我们考虑稳定后的情况。
model:
sets:
days/mon..sun/: required,start;
endsets
data:
!每天所需的最少职员数;
required = 20 16 13 16 19 14 12;
enddata
!最小化每周所需职员数;
min=@sum(days:start);
@for(days(J):
@sum(days(I) | I #le# 5: start(@wrap(J+I+2,7))) >= required(J));
end
今天第一次遇到这样的问题,说一下对这个题的感受:1、语法陌生,表示不能理解;2、@wrap不知道是什么东西,原以为是曲波里面的wrapping算法,还是多想了;
首先我们就从wrap算法说起,他到底是什么意思,最重要的是@wrap的返回值是什么,举个例子来说,wrap(2,5)=2,wrap(6,5)=1;wrap(40,8)=8;
wrap(A,B)意思是C=A-B*K;K为一个适当的值,使得C落在区间[1,B]之间;若A<=B则直接返回A;
wrap算法不知道您理解了没,接下来看一下程序部分:
我的理解,不对的或表达错误的还望见谅!
为什么要按照每天安排多少人(新添入的护士)来计算,而不是每天实际上班人数?这个问题我开始也不能理解,我们不妨这样理解:每天的实际上班人数都是由前五天导致的!为什么这么说?请看:
满足两个条件:1、每天至少有x人工作;2、每个人需要连续工作5天;如果按照每天实际上班人数来安排情况是多么复杂,相反的,如果只考虑每天医院安排的(新加入的护士)这样就简单多了,这样一来每天具体的工作人数就可以表达为:
星期J工作的人数=星期J新加入的护士+星期J-1新加入的护士+星期J-2新加入的护士+星期J-3新加入的护士+星期J-4新加入的护士
星期J工作的人数>=当天的最少工作人数的需求
这句代码就表达了这个意思:
@sum(days(I) | I #le# 5: start(@wrap(J+I+2,7))) >= required(J));
这样一来就是的总的目标言简意赅,我们的关注点一定要转移到每天新加入的护士,因为一旦加入她(他)必须要连续工作5天!
2015.8.5 17:16 星期三 暴雨