2018/9/11更正
- 用intlinprog可以求解整数规划。当时大概是参考资料比较早以为matlab不能求解整数规划(挠头),而且找到的代码是用线性规划解的,所以就没有多考虑。谢谢评论指出。
- 下面证明的截图打字进去搜能找到原文,但是是lingo的一个非正式教材,并没有说明“什么是特例”以及给出证明。我大概找了一下没有找到相关资料。
- 01规划问题的常用解法不存在用线性规划去近似。我觉得这种解法应该是有问题的虽然我不知道怎么证伪……啊当时只想着解出来所以犯错了
原文
指派问题最广泛通俗的解法应该是匈牙利算法但在网上找不到这方面的代码。
线性规划求解
网上比较常用的解法是用线性规划求解,但好像没有人去解释为什么?而且这个代码本身也有一定的问题。
我好像也给不出非常严谨的证明……只能说感觉里,在某些情况下如果只有一个最优解那么它的每个解一定是趋向于0或者1的(就是感觉里应该是单调的?)
后来好像有什么人给出过证明(我就留了张截图)
上图给我带来了对人生的一段认真的思考……
某些问题
然后这个代码对于多个最优解的情况会出问题。
比方说
Task | A | B |
---|---|---|
Task1 | 3 | 5 |
Task2 | 5 | 3 |
可以得到一个正常的解
那么对于
Task | A | B |
---|---|---|
Task1 | 3 | 5 |
Task2 | 3 | 5 |
就算能够得到解也不是一个01规划了
更何况对于三个人的情况……
Task | A | B | C |
---|---|---|---|
Task1 | 3 | 5 | 7 |
Task2 | 3 | 5 | 7 |
Task2 | 3 | 5 | 7 |
这样子求出的3*3矩阵全是1/3也是一种合理的解,但是它毕竟不是一个01整数规划一旦取整显然就凉了……得出的就都是0.
然后某只鸟的解决方法是加个随机的扰动……打破这种迷之稳定的状态就好了……然后多按两下可以看看不同的解(但是没法保证按出来的结果是所有解……)
能够得到多个解在某些时候是有用的(比如论文不够长的时候)。比方说对于一堆任务,每个人去实现每一项都会有雇佣成本和能取得的收入,求解的时候可以用01整数规划求出净利润最高的一系列方案,然后再在这一系列方案中找一个雇佣成本最低的方案这样。
还有就是任务比人多的时候可以填几个无关工作。所有人处理这个工作的效率都一样就好了(突然想到不知道这些工作是加噪声效率高还是不加高)
然后这个解的问题……其实在过程中想过要目标函数是(完成时间最大值)的最小值的,就是让所有工作的完成时间最短。尝试了一下matlab的非线性规划然后失败了……虽然不太理解但感觉里会是分段函数(还是每段都是平的一条那种)应该是陷入局部最优了?反正解起来都走不出我给的初始条件……matlab的整数规划没法解非线性的方程大概还是要学一下Lingo……
下面一份是网上比较容易找到的代码。
%适用于任意n阶系数矩阵
clear all;
C=[2 15 13 4;10 4 14 15;9 14 16 13;7 8 11 9];%效率矩阵C
n=size(C,1);%计算C的行列数n
C=C(:);%计算目标函数系数,将矩阵C按列排成一个列向量即可。
%%%这里加入一个很小的扰动
%C = C + randn(n)/1000;
A=[];B=[];%没有不等式约束
Ae=zeros(2*n,n^2);%计算等约束的系数矩阵a
for i=1:n
for j=(i-1)*n+1:n*i
Ae(i,j)=1;
end
for k=i:n:n^2
Ae(n+i,k)=1;
end
end
Be=ones(2*n,1);%等式约束右端项b
Xm=zeros(n^2,1);%决策变量下界Xm
XM=ones(n^2,1);%决策变量上界XM
[x,z]=linprog(C,A,B,Ae,Be,Xm,XM);%使用linprog求解
x=reshape(x,n,n);%将列向量x按列排成一个n阶方阵
disp('最优解矩阵为:');%输出指派方案和最优值
Assignment=round(x)%使用round进行四舍五入取整
disp('最优解为:');
z
然后觉得蛮神奇的是用这种规划的形式吧(反正我想不到可以这样?)哇加油加油。