使用内点法解决线性规划问题
1. 问题描述
这里以一个简单的线性函数为例子:
min x+ys.t. x+2y≤10 2x+y≤10 x≥0 y≥0
最终,可行域在下图中中间那部分,结合图像可以很容易的得到最优值为0。但是如何要使用程序从可行域的某个起始点收敛到最优值。

2. 问题建模
线性规划问题的一般形式为:
min cTXs.t. AX≤b
因此,对上一部分的那个例子按照这种形式表示,设c=(11),A=⎝⎜⎜⎛12−10210−1⎠⎟⎟⎞,b=⎝⎜⎜⎛1100⎠⎟⎟⎞,X=(xy),则原始问题可以表示为线性规划的一般形式。
使用拉格朗日方法将问题的目标与问题的约束条件放到一个函数里面,得到下面这个函数:
f(x)=cTX+i=1∑mI(AjXj−b)
其中指示函数的定义为:
I(x)={x,+∞,x≤0x>0
使用该指示函数可以确保最终的最小值一定是符合函数的约束条件的,但是这种分段函数存在不可导的点。所以,使用某个可导的函数代替,在这里使用对数函数 −t1log(−x),其函数图像如下所示,其中t越大,则该函数越贴近左侧的x,y坐标轴。

之后,问题的形式变成了:
f(x)=tcTX−i=1∑mlog(−AijXj+bi)
分别求解一阶以及二阶导数,对于X中的每个xk求一阶导得到 ∇fxk=tck−i=1∑mAijXj−biAik,将一阶导数向量化表示为 ∇f=tc−ATAX−b1,同理,二阶导表示为 ∇2f=ATDA, 其中 D=(Ax−b)21.
在算法的开始,在可行域内选取任意一个作为初始点,t的初始值设为一个比较小的数,在迭代过程中慢慢增大t的值。在实际运行中发现,从点(3,3)开始,会逐渐收敛到(1.58,1,58)左右。因此,为了进一步地收敛到最优值,在收敛到某个点后不再继续收敛的情况下,应该继续从该点开始,t重置为一个较小的值。这样最终可以收敛到(0,0)点。
代码实现已上传到Github,链接。