最优化方法Python计算:标准型线性规划的轴转操作

标准型线性规划
{ minimize c ⊤ x s.t. A x = b x ≥ o ( 1 ) \begin{cases} \text{minimize}\quad\boldsymbol{c}^\top\boldsymbol{x}\\ \text{s.t.}\quad\quad\boldsymbol{Ax}=\boldsymbol{b}\\ \quad\quad\quad\quad\boldsymbol{x}\geq\boldsymbol{o} \end{cases}\quad\quad\quad(1) minimizecxs.t.Ax=bxo(1)
其中, c \boldsymbol{c} c x ∈ R n \boldsymbol{x}\in\text{R}^n xRn A ∈ R m × n \boldsymbol{A}\in\text{R}^{m\times n} ARm×n m ≤ n m\leq n mn且rank A = m \boldsymbol{A}=m A=m b ∈ R m \boldsymbol{b}\in\text{R}^m bRm b ≥ o \boldsymbol{b}\geq\boldsymbol{o} bo。设 A = ( α 1 , α 2 ⋯   , α n ) \boldsymbol{A}=(\boldsymbol{\alpha}_1,\boldsymbol{\alpha}_2\cdots,\boldsymbol{\alpha}_n) A=(α1,α2,αn) B \boldsymbol{B} B A \boldsymbol{A} A m m m个线性无关列向量构成,满足 B − 1 b ≥ b \boldsymbol{B}^{-1}\boldsymbol{b}\geq\boldsymbol{b} B1bb,称为标准型线性规划(1)的一个基矩阵,其列向量下标集记为 B i n d B_{ind} Bind A \boldsymbol{A} A中去掉 B \boldsymbol{B} B剩下部分记为 N \boldsymbol{N} N,称为(1)的对应 B \boldsymbol{B} B非基矩阵,其列向量下标集记为 N i n d N_{ind} Nind。于是线性方程组 A x = b \boldsymbol{Ax}=\boldsymbol{b} Ax=b可写为 ( B , N ) ( x B x N ) = b (\boldsymbol{B},\boldsymbol{N})\begin{pmatrix}\boldsymbol{x}_{\boldsymbol{B}}\\\boldsymbol{x}_{\boldsymbol{N}}\end{pmatrix}=\boldsymbol{b} (B,N)(xBxN)=b,即
B x B + N x N = b , \boldsymbol{B}\boldsymbol{x}_{\boldsymbol{B}}+\boldsymbol{N}\boldsymbol{x}_{\boldsymbol{N}}=\boldsymbol{b}, BxB+NxN=b,
亦即
x B = B − 1 b − B − 1 N x N . \boldsymbol{x}_{\boldsymbol{B}}=\boldsymbol{B}^{-1}\boldsymbol{b}-\boldsymbol{B}^{-1}\boldsymbol{N}\boldsymbol{x}_{\boldsymbol{N}}. xB=B1bB1NxN.
令自由未知量 x N = o \boldsymbol{x}_{\boldsymbol{N}}=\boldsymbol{o} xN=o得到 A x = b \boldsymbol{Ax}=\boldsymbol{b} Ax=b的解 x 0 = ( x B x N ) = ( B − 1 b o ) \boldsymbol{x}_0=\begin{pmatrix}\boldsymbol{x}_{\boldsymbol{B}}\\\boldsymbol{x}_{\boldsymbol{N}}\end{pmatrix}=\begin{pmatrix}\boldsymbol{B}^{-1}\boldsymbol{b}\\\boldsymbol{o}\end{pmatrix} x0=(xBxN)=(B1bo)称为问题(1)的一个初始基本可行解。对初始基本可行解,对应的目标函数值 f ( x 0 ) = c ⊤ x 0 = c B ⊤ x B + c N ⊤ x N = c B ⊤ x B = c B ⊤ B − 1 b f(\boldsymbol{x}_0)=\boldsymbol{c}^\top\boldsymbol{x}_0=\boldsymbol{c}_{\boldsymbol{B}}^\top\boldsymbol{x}_{\boldsymbol{B}}+\boldsymbol{c}_{\boldsymbol{N}}^\top\boldsymbol{x}_{\boldsymbol{N}}=\boldsymbol{c}_{\boldsymbol{B}}^\top\boldsymbol{x}_{\boldsymbol{B}}=\boldsymbol{c}_{\boldsymbol{B}}^\top\boldsymbol{B}^{-1}\boldsymbol{b} f(x0)=cx0=cBxB+cNxN=cBxB=cBB1b。对任意的 x N ≥ o \boldsymbol{x}_{\boldsymbol{N}}\geq\boldsymbol{o} xNo x = ( x B x N ) \boldsymbol{x}=\begin{pmatrix}\boldsymbol{x}_{\boldsymbol{B}}\\\boldsymbol{x}_{\boldsymbol{N}}\end{pmatrix} x=(xBxN),考虑目标函数
f ( x ) = c ⊤ x = c B ⊤ x B + c N ⊤ x N = c B ⊤ ( B − 1 b − B − 1 N x N ) + c N ⊤ x N = c B ⊤ B − 1 b − ( c B ⊤ B − 1 N x N − c N ⊤ x N ) = f ( x 0 ) − ( c B ⊤ B − 1 N − c N ⊤ ) x N . \begin{align*} f(\boldsymbol{x})&=\boldsymbol{c}^\top\boldsymbol{x}=\boldsymbol{c}_{\boldsymbol{B}}^\top\boldsymbol{x}_{\boldsymbol{B}}+\boldsymbol{c}_{\boldsymbol{N}}^\top\boldsymbol{x}_{\boldsymbol{N}}\\ &=\boldsymbol{c}_{\boldsymbol{B}}^\top(\boldsymbol{B}^{-1}\boldsymbol{b}-\boldsymbol{B}^{-1}\boldsymbol{N}\boldsymbol{x}_{\boldsymbol{N}})+\boldsymbol{c}_{\boldsymbol{N}}^\top\boldsymbol{x}_{\boldsymbol{N}}\\ &=\boldsymbol{c}_{\boldsymbol{B}}^\top\boldsymbol{B}^{-1}\boldsymbol{b}-(\boldsymbol{c}_{\boldsymbol{B}}^\top\boldsymbol{B}^{-1}\boldsymbol{N}\boldsymbol{x}_{\boldsymbol{N}}-\boldsymbol{c}_{\boldsymbol{N}}^\top\boldsymbol{x}_{\boldsymbol{N}})\\ &=f(\boldsymbol{x}_0)-(\boldsymbol{c}_{\boldsymbol{B}}^\top\boldsymbol{B}^{-1}\boldsymbol{N}-\boldsymbol{c}_{\boldsymbol{N}}^\top)\boldsymbol{x}_{\boldsymbol{N}}. \end{align*} f(x)=cx=cBxB+cNxN=cB(B1bB1NxN)+cNxN=cBB1b(cBB1NxNcNxN)=f(x0)(cBB1NcN)xN.
z = c B ⊤ B − 1 N \boldsymbol{z}=\boldsymbol{c}_{\boldsymbol{B}}^\top\boldsymbol{B}^{-1}\boldsymbol{N} z=cBB1N,考虑向量 z − c N ⊤ \boldsymbol{z}-\boldsymbol{c}_{\boldsymbol{N}}^\top zcN。只要存在 k ∈ N i n d k\in N_{ind} kNind,使得 z k − c k > 0 z_k-c_k>0 zkck>0,选取其中下标最小者
e = min ⁡ k ∈ N i n d { k ∣ z k − c k > 0 } e=\min_{k\in N_{ind}}\{k|z_k-c_k>0\} e=kNindmin{kzkck>0}
解等式约束条件形成的线性方程组,并令自由未知量 x N = ( 0 ⋮ x e ⋮ 0 ) \boldsymbol{x}_{\boldsymbol{N}}=\begin{pmatrix}0\\\vdots\\x_e\\\vdots\\0\end{pmatrix} xN= 0xe0 ,即
x k = { x e k ∈ N i n d , k = e 0 k ∈ N i n d , k ≠ e x_k=\begin{cases} x_e&k\in N_{ind},k=e\\ 0&k\in N_{ind},k\not=e \end{cases} xk={xe0kNind,k=ekNind,k=e
其中 x e ≥ 0 x_e\geq0 xe0。得
x B = B − 1 b − B − 1 N x N = B − 1 b − B − 1 α e x e = b ˉ − x e y e \boldsymbol{x}_{\boldsymbol{B}}=\boldsymbol{B}^{-1}\boldsymbol{b}-\boldsymbol{B}^{-1}\boldsymbol{N}\boldsymbol{x}_{\boldsymbol{N}}=\boldsymbol{B}^{-1}\boldsymbol{b}-\boldsymbol{B}^{-1}\boldsymbol{\alpha}_ex_e=\bar{\boldsymbol{b}}-x_e\boldsymbol{y}_e xB=B1bB1NxN=B1bB1αexe=bˉxeye
其中, b ˉ = B − 1 b = ( b ˉ 1 b ˉ 2 ⋮ b ˉ m ) \bar{\boldsymbol{b}}=\boldsymbol{B}^{-1}\boldsymbol{b}=\begin{pmatrix}\bar{b}_1\\\bar{b}_2\\\vdots\\\bar{b}_m\end{pmatrix} bˉ=B1b= bˉ1bˉ2bˉm y e = B − 1 α e = ( y e 1 y e 2 ⋮ y e m ) \boldsymbol{y}_e=\boldsymbol{B}^{-1}\boldsymbol{\alpha}_e=\begin{pmatrix}y_{e_1}\\y_{e_2}\\\vdots\\y_{e_m}\end{pmatrix} ye=B1αe= ye1ye2yem 。若 y e ≤ o \boldsymbol{y}_e\leq\boldsymbol{o} yeo,则问题(1)为无界问题。设存在 i ∈ B i n d i\in Bind iBind,使得 y e i > 0 y_{e_i}>0 yei>0,设
l = min ⁡ { j ∣ b ˉ j y e j = min ⁡ i ∈ B i n d { b ˉ i y e i ∣ y e i > 0 } } l=\min\left\{j|\frac{\bar{b}_j}{y_{e_j}}=\min_{i\in B_{ind}}\left\{\frac{\bar{b}_i}{y_{e_i}}|y_{e_i}>0\right\}\right\} l=min{jyejbˉj=iBindmin{yeibˉiyei>0}}
即取 l l l min ⁡ i ∈ B i n d { b ˉ i y e i ∣ y e i > 0 } \min\limits_{i\in B_{ind}}\{\frac{\bar{b}_i}{y_{e_i}}|y_{e_i}>0\} iBindmin{yeibˉiyei>0}中的最小下标( min ⁡ i ∈ B i n d { b ˉ i y e i ∣ y e i > 0 } \min\limits_{i\in B_{ind}}\{\frac{\bar{b}_i}{y_{e_i}}|y_{e_i}>0\} iBindmin{yeibˉiyei>0}可能有多于1个的等值最小者)。将 B \boldsymbol{B} B中的 α l \boldsymbol{\alpha}_l αl N \boldsymbol{N} N中的 α e \boldsymbol{\alpha}_e αe进行交换,即
{ B = ( B − { α l } ) ∪ { α e } N = ( N − { α e } ) ∪ { α l } \begin{cases} \boldsymbol{B}=(\boldsymbol{B}-\{\boldsymbol{\alpha}_l\})\cup\{\boldsymbol{\alpha}_e\}\\ \boldsymbol{N}=(\boldsymbol{N}-\{\boldsymbol{\alpha}_e\})\cup\{\boldsymbol{\alpha}_l\} \end{cases} {B=(B{αl}){αe}N=(N{αe}){αl}
称为问题(1)的一次轴转操作。可以证明,轴转后 B \boldsymbol{B} B仍然是问题(1)的一个基矩阵,且对应的基础可行解 x 1 \boldsymbol{x}_1 x1的目标函数值 f ( x 1 ) < f ( x 0 ) f(\boldsymbol{x}_1)<f(\boldsymbol{x}_0) f(x1)<f(x0)。轴转操作中入基向量下标 e e e和离基限量下标 l l l的选取规则
{ e = min ⁡ k ∈ N i n d { k ∣ z k − c k > 0 } l = min ⁡ { j ∣ b ˉ j y e j = min ⁡ i ∈ B i n d { b ˉ i y e i ∣ y e i > 0 } } \begin{cases} e=\min\limits_{k\in N_{ind}}\{k|z_k-c_k>0\}\\ l=\min\left\{j|\frac{\bar{b}_j}{y_{e_j}}=\min\limits_{i\in B_{ind}}\left\{\frac{\bar{b}_i}{y_{e_i}}|y_{e_i}>0\right\}\right\} \end{cases} e=kNindmin{kzkck>0}l=min{jyejbˉj=iBindmin{yeibˉiyei>0}}
称为Bland法则。下列代码对问题(1)的初始基矩阵 B \boldsymbol{B} B实现轴转过程。

import numpy as np
def pivot(A, b, c, Bind, Nind, z):
    m, _ = A.shape										#A的行数
    B = A[:, Bind]										#基矩阵
    B1 = np.linalg.inv(B)								#基矩阵的逆
    e = np.min(np.where((z - c[Nind]) > 1e-10)[0])		#计算入基向量下标
    ye = np.matmul(B1, A[:, Nind[e]]).flatten()
    infinite = False									#初始化无界标志
    index = np.where(ye > 1e-10)[0]						#ye中正值元素下标
    if index.size = = 0:								#若ye所有元素不超过0
        infinite = True
        return infinite, None, None, None
    b1 = np.matmul(B1, b.reshape(m, 1)).flatten()
    minl = np.min(b1[index] / ye[index])				#计算离基向量下标
    l = min(index[np.where(b1[index] / ye[index] == minl)[0]])
    Bind[l], Nind[e] = Nind[e], Bind[l]					#轴转
    B = A[:, Bind]										#基矩阵
    B1 = np.linalg.inv(B)								#基矩阵的逆
    w = np.matmul(c[Bind], B1)
    z = np.matmul(w, A[:, Nind]).flatten()				#构造判别式中的z
    return infinite, Bind, Nind, z

函数pivot的参数A,b,c分别表示待解标准型线性规划的等式约束系数矩阵 A \boldsymbol{A} A,常数向量 b \boldsymbol{b} b和目标函数系数向量 c \boldsymbol{c} c。参数Bind和Nind分别表示初始基矩阵 B \boldsymbol{B} B和非基矩阵 N \boldsymbol{N} N的列向量在 A \boldsymbol{A} A中的下标数组。
函数体中第4行,用Bind作为列标,读取A中列向量组成基矩阵 B \boldsymbol{B} B,赋予B。第5行调用Numpy.linalg包的inv函数,计算 B − 1 \boldsymbol{B}^{-1} B1赋予B1。第6行按Bland规则计算入基向量下标e。第7行利用e计算向量 y e = B − 1 α e \boldsymbol{y}_e=\boldsymbol{B}^{-1}\boldsymbol{\alpha}_e ye=B1αe赋予ye。第9行用Numpy的where函数计算ye中大于零的元素下标,赋予数组index。第10~12行的if语句,根据ye中元素是否全非正,设置无界标志infinite为True(infinite在第8行初始化为False),并返回infinite及3个空集。第13行计算向量 b ˉ = B − 1 b \bar{\boldsymbol{b}}=\boldsymbol{B}^{-1}\boldsymbol{b} bˉ=B1b赋予b1。第14~15行按Bland规则计算立即向量下标赋予l。第16通过交换Bind和Nind中元素的方式行执行轴转操作
{ B = ( B − { α l } ) ∪ { α e } N = ( N − { α e } ) ∪ { α l } . \begin{cases} \boldsymbol{B}=(\boldsymbol{B}-\{\boldsymbol{\alpha}_l\})\cup\{\boldsymbol{\alpha}_e\}\\ \boldsymbol{N}=(\boldsymbol{N}-\{\boldsymbol{\alpha}_e\})\cup\{\boldsymbol{\alpha}_l\} \end{cases}. {B=(B{αl}){αe}N=(N{αe}){αl}.
第17、18行分别计算轴转后的基矩阵及其逆阵。第19~20行计算向量 z = c B ⊤ B − 1 N \boldsymbol{z}=\boldsymbol{c}_{\boldsymbol{B}}^\top\boldsymbol{B}^{-1}\boldsymbol{N} z=cBB1N,赋予z。第21行返回infinite, Bind,Nind和z。
例1:标准型线性规划
{ minimize − x 1 − 5 x 2 s.t. 5 x 1 + 6 x 2 + x 3 = 30 3 x 1 + 2 x 2 + x 4 = 12 x 1 , x 2 , x 3 , x 4 ≥ 0 \begin{cases} \text{minimize}\quad-x_1-5x_2\\ \text{s.t.}\quad\quad\quad 5x_1+6x_2+x_3=30\\ \quad\quad\quad\quad 3x_1+2x_2+x_4=12\\ \quad\quad\quad\quad x_1,x_2,x_3,x_4\geq0 \end{cases} minimizex15x2s.t.5x1+6x2+x3=303x1+2x2+x4=12x1,x2,x3,x40
目标函数 f ( x ) = − x 1 − 5 x 2 = c ⊤ x f(\boldsymbol{x})=-x_1-5x_2=\boldsymbol{c}^\top\boldsymbol{x} f(x)=x15x2=cx,其中 x ∈ R 4 \boldsymbol{x}\in\text{R}^4 xR4 c ⊤ = ( − 1 , − 5 , 0 , 0 ) \boldsymbol{c}^\top=(-1,-5,0,0) c=(1,5,0,0)。等式约束系数矩阵和常数向量
A = ( 5 6 1 0 3 2 0 1 ) , b = ( 30 12 ) . \boldsymbol{A}=\begin{pmatrix}5&6&1&0\\3&2&0&1\end{pmatrix},\boldsymbol{b}=\begin{pmatrix}30\\12\end{pmatrix} . A=(53621001),b=(3012).
取基矩阵 B 1 = ( α 3 , α 4 ) = I \boldsymbol{B}_1=(\boldsymbol{\alpha}_3,\boldsymbol{\alpha}_4)=\boldsymbol{I} B1=(α3,α4)=I,非基矩阵 N 1 = ( α 1 , α 2 ) \boldsymbol{N}_1=(\boldsymbol{\alpha}_1,\boldsymbol{\alpha}_2) N1=(α1,α2)。对应的基本可行解 x 1 = ( 0 0 30 12 ) \boldsymbol{x}_1=\begin{pmatrix}0\\0\\30\\12\end{pmatrix} x1= 003012 x B = ( 30 12 ) \boldsymbol{x}_{\boldsymbol{B}}=\begin{pmatrix}30\\12\end{pmatrix} xB=(3012) x N 1 = o \boldsymbol{x}_{\boldsymbol{N}_1}=\boldsymbol{o} xN1=o c B 1 ⊤ = ( 0 , 0 ) \boldsymbol{c}_{\boldsymbol{B}_1}^\top=(0,0) cB1=(0,0) c N 1 ⊤ = ( − 1 , − 5 ) \boldsymbol{c}_{\boldsymbol{N}_1}^\top=(-1,-5) cN1=(1,5),目标函数值 f ( x 0 ) = c B 1 ⊤ x B 1 + c N 1 ⊤ x N 1 = 0 f(\boldsymbol{x}_0)=\boldsymbol{c}_{\boldsymbol{B}_1}^\top\boldsymbol{x}_{\boldsymbol{B}_1}+\boldsymbol{c}_{\boldsymbol{N}_1}^\top\boldsymbol{x}_{\boldsymbol{N}_1}=0 f(x0)=cB1xB1+cN1xN1=0。下列代码对基矩阵 B 1 \boldsymbol{B}_1 B1作轴转操作

import numpy as np									#导入numpy
from fractions import Fraction as F					#设置有理数输出格式
np.set_printoptions(formatter = {'all':lambda x:
                               str(F(x).limit_denominator())})
A = np.array([[5, 6, 1, 0],							#设置系数矩阵
              [3, 2, 0, 1]])
b = np.array([30, 12])								#设置常数向量
c = np.array([-1, -5, 0, 0])						#设置目标函数系数向量
Bind = np.array([2, 3])								#初始基矩阵列向量下标集
Nind = np.setdiff1d(np.arange(4), Bind)				#初始非基矩阵列向量下标集
B = A[:, Bind]										#初始基矩阵
B1 = np.linalg.inv(B)								#逆矩阵
w = np.matmul(c[Bind], B1)
z = np.matmul(w, A[:, Nind]).flatten()				#计算向量z
_, Bind, Nind, _ = pivot(A, b, c, Bind, Nind, z)	#轴转
print(Bind, Nind)
B = A[:, Bind]										#新的基矩阵
B1 = np.linalg.inv(B)
xB = np.matmul(B1, b.reshape(b.size,1)).flatten()	#基变量解
x = np.zeros(4)										#初始化可行解
x[Bind] = xB										#填充基变量值
f = np.dot(c, x)									#目标函数值
print(x, f)

代码中第2~4行设置输出数据为有理数(分数)格式。第5~8行设置本题标准型线性规划的等式约束系数矩阵,常数向量,目标函数系数向量A、b、c。第9、10行分别设置初始基矩阵和非基矩阵的列向量下标。13~14行计算判别向量中的z。第15行调用pivot函数计算轴转,将返回值中Bind,Nind赋予同名变量。17、18行重新计算基矩阵B及其逆矩阵B1。第19行计算基变量解,20~21行计算新的基本可行解x,22行计算新的基本可行解处函数值。运行程序,输出

[2 0] [3 1]
[4 0 10 0] -4.0

第1行表示新的基矩阵由 α 3 , α 1 \boldsymbol{\alpha}_3,\boldsymbol{\alpha}_1 α3,α1构成(注意Python数组下标从0开始编码),非基矩阵由 α 4 , α 2 \boldsymbol{\alpha}_4,\boldsymbol{\alpha}_2 α4,α2构成。第2行表示对应B的新的基本可行解为 x 1 = ( 4 , 0 , 10 , 0 ) ⊤ \boldsymbol{x}_1=(4,0,10,0)^\top x1=(4,0,10,0),对应的目标函数值为 f ( x 1 ) = − 4 < 0 = f ( x 0 ) f(\boldsymbol{x}_1)=-4<0=f(\boldsymbol{x}_0) f(x1)=4<0=f(x0)
写博不易,敬请支持:
如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值