目标问题 - GMPL

时间:2015-05-28 23:57:16

标签: linear-programming ampl glpk mathprog

我正试图塑造一个目标。

这是一个特殊的分配问题,我希望尽量减少完成所有工作所需的工人。因此,所有工作都必须完成,但并非所有工人都必须做某事。

约束:

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;

有任何新的提示或建议吗?

2 个答案:

答案 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正在完成所有工作。