算法设计与分析-线性规划

作者半个学期都没搞懂线性规划问题,看了无数资料。后面又听了几遍课终于大概懂了一些。现把心得代码列与此,造福同样被算法设计与分析折磨的学弟学妹。
标准形:

min z = c.transpose().dot(x)
s.t. Ax <= b
	for all i, x_i >= 0

单纯形法:
一些概念:
基,基本可行解(即只有在某组基的系数处的x是不为0的)
推导:采用向量形式。加入松弛变量化成:

min z = c.transpose().dot(x)
s.t. A*x' == b
	for all i, x_i >= 0

等式两边同乘B的逆(这里我傻了,实际上A不是方阵,是mxn的,B才是方阵,是含有逆的)

np.dot(np.dot(np.linalg.inv(B), A),x) = np.linalg.inv(B).dot(b)

(下面用伪代码了,看得懂就好,打numpy代码太累了)
下面的推导:

B-1*A*x = B-1*b
Ax = B*x_B + N*x_N
x_B + B-1*N*x_N = B-1*b
# 代入最初的式子
z = c.transpose() * x
   = c_B.transpose() * x_B + c_N.transpose() * x_N
   = c_B.transpose() * (B-1*b - B-1*N*x_N) + c_N.transpose() * x_N
   = c_B.transpose() * B-1 * b + (c_N.transpose() - c_B.transpose() * B-1 * N) *x_N
   = c_B.t * B-1 * b + (c_B.t - c_B.t * B-1 * B)*x_B + (c_N.t - c_B.t * B-1 * N) *x_N
   = c_B.t * B-1 *b + (c_t -c_B.t * B-1 *A) * x

把前一项记做z0,后一项的系数记做\lambda,就得到了线性变换单纯形法的标准式
然后我们的目标是将初始可行解通过变换得到最优解。最优解满足z的那个所有的lambda系数都大于等于0,这样的话只要让系数不为0的x_i都为0,就可以让z取得极值。否则x可以趋向于无穷大。原来的目标函数没有最优解。
如果有哪个lambda小于0,这个x是无法去限制的。我们要把这个x换出来。定理已经有证明,换出x之后的解还是基本可行解。按照定理的方法,如果所有的alpha[i,k]都小于等于0(对所有i),那么这个问题无解。因为我们只要把其他的x都取成0,alpha[i,k]对应的x可以取成无穷大,松弛变量看着取。仍旧满足小于等于b的条件。
然后对所有alpha大于0做运算,取beta/alpha最小的那个换出来。这样换是和前面定理的证明一致的,要保证新的解仍然是可行解,就要保证所有的beta大于等于0。而theta实际上就是所有beta要减去的量,保证这个量大于0.
然后就是对矩阵做变换。把换进去的那个变量对应的那一列换成epsilon(即把换进去的变量的系数都变成1),把对应的lambda消成0(这些解都不取0,其他lambda不为0的x都取0值从而保证最优性),z也相应消。注意这里z和lambda和上面的x和alpha形式上保持统一,z0记录在beta那一列,要取相反数。
然后一直循环到终止条件。

然后是人工变量和两阶段法。前面只讨论了小于等于b的情况,要考虑大于等于b的情况(最后也可以转化成等于的情形)。这时候加入人工变量(最后人工变量需要全取0),解决辅助问题min w = 所有人工变量之和。如果w等于0,说明原问题有解,否则没有解。
最后得到一组可行解。如果不含人工变量,直接把人工变量删掉,重新单纯形法求解,否则然后变形的alpha beta集合做处理:或者删去线性相关(即原变量的系数都为0)的列,否则就换出某个系数不为0的变量再迭代,最后化归成前一种情况。
注意这里的话在两个阶段之中,z0和所有的lambda值都是要重新算的。这是因为在简单单纯形法里面我们直接选了所有的松弛变量(系数都是1)作为基本解,不会在z当中出现,B = E,c_B.t * b = 0 * b = 0.即z0=0,lambda = c.t。就不用另外算。
然后就开始求解就行了。

对偶规划:
主要的定理是原始规划和对偶规划同时取得最优解。然后保证一个规划可行的同时另一个规划旋转取最优。(如果目标函数有一个无界的话,其对偶规划无最优解)
正则基:对应的lambda大于等于0
可以证明如果B是正则基,则y是可行解。实际上就是保证所有的lambda大于等于0的同时对x做变换让它成为可行解,即,使所有的beta大于等于0.就是把单纯形法反过来了一下。

作者实现了前两种单纯形法。至于第三种稍作修改即可。
实现代码链接:
https://github.com/Murphy-OrangeMud/Algorithm-Analysis
欢迎提出issue

然后说一下整数线性规划。
用分支限界算法即可。对相应的松弛算法求解,如果满足整数要求就直接输出,否则施加条件 x <= 下取整alpha和x >= 上取整 alpha分别进行求解和迭代。递归实现。
这个就没实现啦。加一个递归函数,把单纯形法封装一下应该就可了。

你可能感兴趣的:(算法)