引言
对偶理论是运筹学里面非常重要的知识点,我一直想直观地理解对偶理论的来龙去脉。但是,现有的介绍对偶理论的文章通常在开头就直接给出原问题和对偶问题的表达式,没有一个自然地“引出”对偶问题的过程。最近读了《Introduction to Operations Research》,非常喜欢里面对于对偶理论的引出和解释,仅以此文作为学习笔记。
1 从单纯形法说起
《Introduction to Operations Research》中反复用到了如下的例子,称为“Wyndor Glass Co. Problem”。
用单纯形法求解的过程如下:
0到1、1到2的这两步,其实就是矩阵的初等行变换。由线性代数的知识可以知道,第
更精巧的是,从0到任意第
这里的“基变量”,指的是已经完成入基和出基操作之后的基变量。这里的“重新排列”指的是在初始的约束方程组的基向量矩阵
具体的过程详见下面的手写笔记。
每一步变换的
import numpy as np
B_1 = np.matrix([[1., 0., 0.],
[0., 2., 0.],
[0., 2., 1.]])
B_1_I = B_1.I
print("B_1_I")
print(B_1_I)
print("n")
B_2 = np.matrix([[1., 0., 1.],
[0., 1., 0.],
[0., 0., 3.]])
B_2_I = B_2.I
print("B_2_I")
print(B_2_I)
print("n")
B_3 = np.matrix([[1., 0., 1.],
[0., 2., 0.],
[0., 2., 3.]])
B_3_I = B_3.I
print("B_3_I")
print(B_3_I)
print("n")
print("B_2_I*B_1_I")
print(B_2_I*B_1_I)
print("n")
# IF B_3_I = B_x *B_1_I, B_x = B_3_I *B_1_I.I
B_x = B_3_I *B_1_I.I
print("B_x.I")
print(B_x.I)
print("n")
这样一来,我们就得到了一个很有意思的结论:
从初始的单纯形表迭代任意次,其结果都可以表示为如下形式:
其中,
2 对偶问题的引出:单纯形表的另一种解释
由上一部分的结论可以看出,无论迭代多少次,单纯形表的第一行总可以写成以下形式:
Row 0决定了该次迭代是否达到最优。假设该次迭代达到最优,根据最优解的判别条件,可以得到原问题的对偶问题:
换言之,从单纯形法的角度来说,对偶问题描述了通过单纯形法求解原问题的优化目标。
从下面这张表可以看出,通过单纯形表解原问题的过程中,表0和表1的对偶问题的解都不在可行域中(不满足
由此,可以很直观地得到以下两个结论:
弱对偶性,Weak duality property:对于原问题的可行解
强对偶性,Strong duality property:对于原问题的最优解