最优化方法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) ⎩ ⎨ ⎧minimizec⊤xs.t.Ax=bx≥o(1)

其中, c \boldsymbol{c} c、 x ∈ R n \boldsymbol{x}\in\text{R}^n x∈Rn, A ∈ R m × n \boldsymbol{A}\in\text{R}^{m\times n} A∈Rm×n, m ≤ n m\leq n m≤n且rank A = m \boldsymbol{A}=m A=m, b ∈ R m \boldsymbol{b}\in\text{R}^m b∈Rm且 b ≥ o \boldsymbol{b}\geq\boldsymbol{o} b≥o。设 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} B−1b≥b,称为标准型线性规划(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=B−1b−B−1NxN.

令自由未知量 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)=(B−1bo)称为问题(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)=c⊤x0=cB⊤xB+cN⊤xN=cB⊤xB=cB⊤B−1b。对任意的 x N ≥ o \boldsymbol{x}{\boldsymbol{N}}\geq\boldsymbol{o} xN≥o, 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)=c⊤x=cB⊤xB+cN⊤xN=cB⊤(B−1b−B−1NxN)+cN⊤xN=cB⊤B−1b−(cB⊤B−1NxN−cN⊤xN)=f(x0)−(cB⊤B−1N−cN⊤)xN.

令 z = c B ⊤ B − 1 N \boldsymbol{z}=\boldsymbol{c}{\boldsymbol{B}}^\top\boldsymbol{B}^{-1}\boldsymbol{N} z=cB⊤B−1N,考虑向量 z − c N ⊤ \boldsymbol{z}-\boldsymbol{c}{\boldsymbol{N}}^\top z−cN⊤。只要存在 k ∈ N i n d k\in N_{ind} k∈Nind,使得 z k − c k > 0 z_k-c_k>0 zk−ck>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=k∈Nindmin{k∣zk−ck>0}

解等式约束条件形成的线性方程组,并令自由未知量 x N = ( 0 ⋮ x e ⋮ 0 ) \boldsymbol{x}{\boldsymbol{N}}=\begin{pmatrix}0\\\vdots\\x_e\\\vdots\\0\end{pmatrix} xN= 0⋮xe⋮0 ,即
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={xe0k∈Nind,k=ek∈Nind,k=e

其中 x e ≥ 0 x_e\geq0 xe≥0。得
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=B−1b−B−1NxN=B−1b−B−1α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ˉ=B−1b= bˉ1bˉ2⋮bˉ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=B−1αe= ye1ye2⋮yem 。若 y e ≤ o \boldsymbol{y}e\leq\boldsymbol{o} ye≤o,则问题(1)为无界问题 。设存在 i ∈ B i n d i\in Bind i∈Bind,使得 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{j∣yejbˉj=i∈Bindmin{yeibˉi∣yei>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\} i∈Bindmin{yeibˉi∣yei>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\} i∈Bindmin{yeibˉi∣yei>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=k∈Nindmin{k∣zk−ck>0}l=min{j∣yejbˉj=i∈Bindmin{yeibˉi∣yei>0}}

称为Bland法则 。下列代码对问题(1)的初始基矩阵 B \boldsymbol{B} B实现轴转过程。

python 复制代码
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} B−1赋予B1。第6行按Bland规则计算入基向量下标e。第7行利用e计算向量 y e = B − 1 α e \boldsymbol{y}_e=\boldsymbol{B}^{-1}\boldsymbol{\alpha}_e ye=B−1α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ˉ=B−1b赋予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=cB⊤B−1N,赋予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} ⎩ ⎨ ⎧minimize−x1−5x2s.t.5x1+6x2+x3=303x1+2x2+x4=12x1,x2,x3,x4≥0

目标函数 f ( x ) = − x 1 − 5 x 2 = c ⊤ x f(\boldsymbol{x})=-x_1-5x_2=\boldsymbol{c}^\top\boldsymbol{x} f(x)=−x1−5x2=c⊤x,其中 x ∈ R 4 \boldsymbol{x}\in\text{R}^4 x∈R4, 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)=cB1⊤xB1+cN1⊤xN1=0。下列代码对基矩阵 B 1 \boldsymbol{B}_1 B1作轴转操作

python 复制代码
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行计算新的基本可行解处函数值。运行程序,输出

python 复制代码
[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)。
写博不易,敬请支持:

如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!

相关推荐
程序媛小果3 分钟前
基于Django+python的Python在线自主评测系统设计与实现
android·python·django
minstbe3 分钟前
WEB开发 - Flask 入门:Jinja2 模板语法进阶 Python
后端·python·flask
黑色叉腰丶大魔王10 分钟前
数据挖掘:定义、挑战与应用
人工智能·数据挖掘
Adenialzz18 分钟前
Rectified Flow 原理简介与示例代码解读
人工智能·深度学习·机器学习·计算机视觉·diffusion
就一枚小白36 分钟前
UE--如何用 Python 调用 C++ 及蓝图函数
c++·python·ue5
m0_7482347138 分钟前
Python大数据可视化:基于spark的短视频推荐系统的设计与实现_django+spider
python·spark·django
看星猩的柴狗1 小时前
机器学习-高斯混合模型
人工智能·机器学习
--FGC--1 小时前
【第2篇】 Python与数据库基础
数据库·python·oracle
m0_630520641 小时前
Python初识
开发语言·python
power-辰南2 小时前
机器学习之数据分析及特征工程详细分析过程
人工智能·python·机器学习·大模型·特征