我正试图塑造一个目标。
这是一个特殊的分配问题,我希望尽量减少完成所有工作所需的工人。因此,所有工作都必须完成,但并非所有工人都必须做某事。
约束:
s.t. AllJobsHaveToBeDone {j in Jobs}:
sum {w in Workers} WhichWorkerDoWhichJob[w,j]=1;
s.t. JustDoWhatHeCanDo {w in Worker, j in Jobs}:
WhichWorkerDoWhichJob[w,j] <= WhatCanHeDo[e, j];
但我无法尽量减少目标中的工人数量。 有没有办法计算实际工作的变量中的工人,然后最小化该变量?
我对它很新,有什么建议吗?
set Jobs;
set Workers;
param WhatCanHeDo{w in Workers, j in Jobs}, binary;
param M;
var WhichWorkerDoWhichJob {w in Workers, j in Jobs}, binary;
var Y{w in Workers}, binary;
s.t. AllJobsHaveToBeDone {j in Jobs}:
sum {w in Workers} WhichWorkerDoWhichJob[w,j]=1;
s.t. JustDoWhatHeCanDo {w in Workers, j in Jobs}:
WhichWorkerDoWhichJob[w,j] <= WhatCanHeDo[w, j];
s.t. Newrule{w in Workers, j in Jobs}:
WhichWorkerDoWhichJob[w,j] >= M * Y[w];
minimize target: sum{w in Workers} Y[w];
solve;
printf "------------------------------------------\n" ;
#To check the values of each Y[w] -> but all will be zeros.
for{w in Workers}
printf "%s %s\n",w,Y[w];
for{w in Workers, j in Jobs:
WhichWorkerDoWhichJob[w,j]=1}
printf "%s do %s job. \n",w,j;
data;
set Jobs:= j1 j2 j3 j4 j5 j6 j7 j8;
set Workers:=w1 w2 w3 w4 w5;
param WhatCanHeDo: j1 j2 j3 j4 j5 j6 j7 j8 :=
w1 1 0 0 0 1 1 1 0
w2 1 1 0 1 0 1 0 0
w3 1 0 1 0 1 0 1 0
w4 1 1 1 0 0 0 1 1
w5 1 0 1 0 0 1 0 0
;
param M:=10000;
end;
有任何新的提示或建议吗?
答案 0 :(得分:0)
您可以按如下方式最小化工人数量
minimize NumWorkers:
sum {w in Workers, j in Jobs} WhichWorkerDoWhichJob[w, j];
其中WhichWorkerDoWhichJob
是一个二进制变量1
,如果工作人员w
执行作业j
。您还需要WhichWorkerDoWhichJob
上的约束,但这些约束取决于问题细节(一个工作人员是否可以执行多个工作等)。
答案 1 :(得分:0)
所以我认为有多种方法可以完成这项工作。大M-Method很不错,但这里并不是绝对必要的,因为你已经定义了二进制变量,glpk可以解决产生的混合整数问题。
因此,对于示例代码的两个小改动,GLPK给了我令人满意的结果。首先,我删除了大M和新规则。其次,我将二进制Y变量添加到您的JustDoWhatHeCanDo约束中:
s.t. JustDoWhatHeCanDo {w in Workers, j in Jobs}:
WhichWorkerDoWhichJob[w,j] <= WhatCanHeDo[w, j] * Y[w];
这将输出w2,w3和w4正在完成所有工作。