matlab reshape_指派问题的Matlab、Lingo、Mathematica及1stOpt求解对比

1. 指派问题

有n项任务要分配给n个人去做,每人只完成一项任务,每个任务也只由一个人完成。已知每人完成每项任务所需的时间效率矩阵C[i,j]如下。问如何分配任务,使完成所有工作所用的总时间最少?

例如:任务为1,2,3,4,人员为1,2,3,4,时间效率矩阵C[i,j]为:

任务1

任务2

任务3

任务4

人员1

2

15

13

4

人员2

10

4

14

5

人员3

9

14

16

13

人员4

7

8

11

9

 2. 模型建立

引入决策变量x[i,j],如果让第i个人去完成第j项任务,则x[i,j] =1,否则x[i,j] = 0,则指派问题的数学模型为:

9567f2b69d58c5e31fd8741ed7b169b2.png

3. Matlab求解

用MATLAB求解线性规划或混合整数规划时,决策变量只能是向量(即一维数组),所以需要把上述数学模型中的双下标常量和决策变量都转化成单下标变量,同时约束也需要进行相应的转换。最终求解代码如下。

Matlab代码:

f=[2,10,9,7,15,4,14,8,13,14,16,11,4,5,13,9];intcon = 1:16;Aeq=[1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0;0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0;0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0;0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1;1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0;0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0;0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0;0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1]beq = ones(8,1);lb=zeros(1,16);ub=ones(1,16);[Y,fval,exitflag] = intlinprog(f,intcon,[],[],Aeq,beq,lb,ub);x=reshape(Y,4,4)fval

Matlab结果输出:

ans =     0     0      0     1     0     1      0     0     1     0      0     0     0     0      1     0Fval = 28

新版MATLAB提供了更具可读性的问题描述及解决方法。

新版Matlab求解代码:

c = [2 15 13 4; 10 4  14 5; 9 14 16 13; 7 8 11 9];prob =  optimproblem('ObjectiveSense', 'min');x = optimvar('x', 4,  4, 'Type', 'integer', 'LowerBound', 0, 'UpperBound', 1);prob.Objective =  sum(sum(c .* x));prob.Constraints.cond1  = sum(x, 1) == 1;prob.Constraints.cond2  = sum(x, 2) == 1;% prob.showproblemsol = prob.solve;sol.x

Matlab结果输出:

LP:                Optimal  objective value is 28.000000.                                           Optimal solution found.Intlinprog stopped at the root node because theobjective value is within a gap tolerance of the optimal value,options.AbsoluteGapTolerance = 0 (the default value). The intcon  variables areinteger within tolerance, options.IntegerTolerance = 1e-05 (the  default value).ans =     0     0      0     1     0     1      0     0     1     0      0     0     0     0      1     0

4. Lingo求解

      用LINGO来求解这个指派问题,只需要会建立集合及其属性,其它就基本上是对数学模型的直接翻译,无需复杂的转换。

Lingo求解代码:

MODEL:DATA:N = 4;ENDDATASETS:AGENTS/1..N/;TASKS/1..N/;MATRIX(AGENTS,TASKS):COST, X;ENDSETSDATA:COST =2,15,13,4,10,4,14,5,9,14,16,137,8,11,9;ENDDATAMIN = @SUM(AGENTS(I) :    @SUM(TASKS(J):  COST(I,J)*X(I,J)));@FOR(AGENTS(I):    @SUM(TASKS(J):X(I,J)) =  1);@FOR(TASKS(J):    @SUM(AGENTS(I):X(I,J)) =  1);@FOR(AGENTS(I):    @FOR(TASKS(J) :  @GIN(X(I,J))));END

Lingo结果输出

Global optimal solution  found.

  Objective value:                     28.00000000000000  Objective bound:                     28.00000000000000  Infeasibilities:                     0.000000000000000  Extended solver  steps:                               0  Total solver  iterations:                              0  Elapsed runtime  seconds:                          0.03  Model Class:                                      PILP  Total variables:                     16  Nonlinear variables:                  0  Integer variables:                   16  Total constraints:                    9  Nonlinear  constraints:                0  Total nonzeros:                      48  Nonlinear nonzeros:                   0              Variable                    Value                 Reduced Cost                     N        4.000000000000000            0.000000000000000           COST( 1, 1)        2.000000000000000            0.000000000000000           COST( 1, 2)        15.00000000000000            0.000000000000000           COST( 1, 3)        13.00000000000000            0.000000000000000           COST( 1, 4)        4.000000000000000            0.000000000000000           COST( 2, 1)        10.00000000000000            0.000000000000000           COST( 2, 2)        4.000000000000000            0.000000000000000           COST( 2, 3)        14.00000000000000            0.000000000000000           COST( 2, 4)        5.000000000000000            0.000000000000000           COST( 3, 1)        9.000000000000000            0.000000000000000           COST( 3, 2)        14.00000000000000            0.000000000000000           COST( 3, 3)        16.00000000000000            0.000000000000000           COST( 3, 4)        13.00000000000000            0.000000000000000           COST( 4, 1)        7.000000000000000            0.000000000000000           COST( 4, 2)        8.000000000000000            0.000000000000000           COST( 4, 3)        11.00000000000000            0.000000000000000           COST( 4, 4)        9.000000000000000            0.000000000000000              X( 1, 1)        0.000000000000000            2.000000000000000              X( 1, 2)        0.000000000000000            15.00000000000000              X( 1, 3)        0.000000000000000            13.00000000000000              X( 1, 4)        1.000000000000000            4.000000000000000              X( 2, 1)        0.000000000000000            10.00000000000000              X( 2, 2)        1.000000000000000            4.000000000000000              X( 2, 3)        0.000000000000000            14.00000000000000              X( 2, 4)        0.000000000000000            5.000000000000000              X( 3, 1)        1.000000000000000            9.000000000000000              X( 3, 2)        0.000000000000000            14.00000000000000              X( 3, 3)        0.000000000000000            16.00000000000000              X( 3, 4)        0.000000000000000            13.00000000000000              X( 4, 1)        0.000000000000000            7.000000000000000              X( 4, 2)        0.000000000000000            8.000000000000000              X( 4, 3)        1.000000000000000            11.00000000000000              X( 4, 4)        0.000000000000000            9.000000000000000                   Row             Slack or Surplus               Dual Price                     1        28.00000000000000           -1.000000000000000                     2        0.000000000000000            0.000000000000000                     3        0.000000000000000            0.000000000000000                     4        0.000000000000000            0.000000000000000                     5        0.000000000000000            0.000000000000000                     6        0.000000000000000            0.000000000000000                     7        0.000000000000000            0.000000000000000                     8        0.000000000000000            0.000000000000000                     9        0.000000000000000            0.000000000000000

5. Mathematica求解

首先进行初始化:

mat = Table[Subscript[a, i, j], {i, 1, 4}, {j, 1, 4}];Cmat = {{2, 15, 13, 4}, {10, 4, 14, 5}, {9, 14, 16, 13}, {7, 8,  11,    9}};

之后使用Minimize函数:

Minimize[{Flatten[mat].Flatten[Cmat],   Table[Sum[mat[[k, i]],  {i, 1, 4}], {k, 1, 4}] == {1, 1, 1, 1},   Table[Sum[mat[[i, k]],  {i, 1, 4}], {k, 1, 4}] == {1, 1, 1, 1}}~  Join~Flatten@   Table[0 <=  Subscript[a, i, j] <= 1, {i, 1, 4}, {j, 1, 4}], Flatten[mat], Integers]

Mathematica结果输出:

{28, {a1.1 -> 0, a1.2 -> 0, a1.3 -> 0, a1.4 -> 1, a2.1  -> 0, a2.2 -> 1, a2.3 -> 0, a2.4 -> 0,a3.1 -> 1, a3.2 -> 0, a3.3 -> 0, a3.4 -> 0, a4.1 ->  0, a4.2 -> 0, a4.3 -> 1, a4.4 -> 0}}

Mathematica结果列为矩阵:

In[67]:= mat /.({28, {a1.1  -> 0, a1.2 -> 0, a1.3 -> 0, a1.4 -> 1, a2.1 -> 0, a2.2 -> 1, a2.3 -> 0, a2.4  -> 0,a3.1 -> 1,  a3.2 -> 0, a3.3 -> 0, a3.4 -> 0,a4.1 ->  0, a4.2 -> 0, a4.3 -> 1, a4.4 -> 0}} [[2]] //MatrixFormOut[67]//MatrixForm(0     0      0     1     0     1      0     0     1     0      0     0     0     0      1     0)

6. 1stOpt求解

1stOpt求解代码:

Constant n=4, c(n,n)=[2,15,13,4,10,4,14,5,9,14,16,13,7,8,11,9];IntParameter x(n,n);Algorithm = LP;MinFunction Sum(i=1:n)(Sum(j=1:n)(c[i,j]*x[i,j]));             For(i=1:n)(Sum(j=1:n)(x[i,j])=1);             For(j=1:n)(Sum(i=1:n)(x[i,j])=1);

1stOpt结果输出:

Objective Function(Min.): 28Best Estimated Parameters:x[1,1]: 0x[1,2]: 0x[1,3]: 0x[1,4]: 1x[2,1]: 0x[2,2]: 1x[2,3]: 0x[2,4]: 0x[3,1]: 1x[3,2]: 0x[3,3]: 0x[3,4]: 0x[4,1]: 0x[4,2]: 0x[4,3]: 1x[4,4]: 0

     对于指派问题,四种软件均可获得相同结果的解。

对不同的版本的Matlab,提供了两种求解方式,第一种比较繁琐,需要进行一些转换工作才能进行求解,第二种相对简单些,两种方式都需要掌握特定命令语句;

Lingo求解,需要熟知Lingo语言中关于集合及其属性的定义,总体上是对数学模型的直接翻译,无需复杂的转换;

Mathematica代码简短,但命令高度抽象,生涩难懂;

1stOpt代码最为直观简洁,与模型公式完全一样。

本文参照知乎贴:https://www.zhihu.com/question/49319704

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MATLAB中,可以使用intlinprog函数来求解指派问题,即混合整数线性规划(MILP)问题。 另外,还可以使用0-1整数规划来解决指派问题,这可以通过编写相应的MATLAB代码来实现。 以下是一个示例MATLAB代码,用于求解指派问题: ```matlab function [y,fval]=zhipai(C) %C为指派n*n系数矩阵 C=C'; f=C(:);%生成一个列向量,作为目标函数系数,matlab默认以列排序 [m,n]=size(C); Aeq=zeros(2*n,n*n);%2*n个等式约束,n*n个变量 for i=1:n %这里先生成的是后四个等式约束的左端项 Aeq(1:n,1+(i-1)*n:i*n)=eye(n,n); end for i=1:n %前四个等式约束左端项 Aeq(i+n,1+(i-1)*n:i*n)=ones(1,n); end beq=ones(2*n,1); lb=zeros(n*n,1); ub=ones(n*n,1); x=linprog(f',[],[],Aeq,beq,lb,ub);%线性规划函数 y=reshape(x,n,n);%将上式求出的x值变成n阶矩阵 y=y';%上式生成的是按列排列的,所以转置一下 y=round(y);%对y元素取整,生成匹配矩阵 sol=zeros(n,n); for i=1:n for j=1:n if y(i,j)==1 sol(i,j)=C(j,i);%匹配矩阵 end end end fval=sum(sol(:));%极小值的目标函数值 ``` 这段代码实现了通过0-1整数规划求解指派问题,并返回了最优解y和目标函数值fval。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [matlab求解指派问题最优解的函数](https://blog.csdn.net/weixin_67016521/article/details/126087775)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [matlab 0-1规划求解指派问题](https://blog.csdn.net/ouzuosong/article/details/52236152)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值