最优化方法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(1) minimizecxs.t.Ax=bxo(1)
B \boldsymbol{B} B为一基矩阵, N \boldsymbol{N} N为对应的非基矩阵。在没遇到判别向量 z − c N ⊤ ≤ o \boldsymbol{z}-\boldsymbol{c}_{N}^\top\leq\boldsymbol{o} zcNo前,轴转操作可重复进行。每做一次,目标函数在新的基本可行解处的函数值都会有所减小。其中, 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}_{N}^\top zcN称为判别向量。直至判别向量非正,则得到最优解。在轴转过程中,选的入基向量下标 e e e后,向量 y e = B − 1 α e \boldsymbol{y}_e=\boldsymbol{B}^{-1}\boldsymbol{\alpha}_e ye=B1αe若非正,则遇到了无界问题,自然无需继续轴转。利用轴转操作时这两个向量的特性,我们可以对可行(具有初始基本可行解)的线性规划(1),写出如下的单纯形算法实现函数。

import numpy as np												#导入numpy
def simplex(A, b, c, Bind, Nind):
    B = A[:, Bind]												#初始基矩阵
    B1 = np.linalg.inv(B)										#基矩阵的逆
    w = np.matmul(c[Bind], B1)
    z = np.matmul(w, A[:,Nind]).flatten()						#构造判别式中的z
    while not(z - c[Nind] <= 1e-10).all():
        infinite, Bind, Nind, z=pivot(A, b, c, Bind, Nind, z)	#轴转
        if infinite:
            print("无界问题...", end=',')
            return None
    return Bind

程序的第2~12行定义的函数simplex,参数A,b,c分别表示标准型线性规划(6.1)的等式约束系数矩阵 A \boldsymbol{A} A,常数向量 b \boldsymbol{b} b和目标函数系数向量 c \boldsymbol{c} c。Bind和Nind分别表示初始基矩阵 B \boldsymbol{B} B的列向量下标和非基矩阵 N \boldsymbol{N} N的列向量下标。函数体内第3行根据Bind计算基矩阵 B \boldsymbol{B} B赋予B。第4行计算 B − 1 \boldsymbol{B}^{-1} B1赋予B1。第5~6行计算向量 z = c B ⊤ B − 1 N \boldsymbol{z}=\boldsymbol{c}_{\boldsymbol{B}}^\top\boldsymbol{B}^{-1}\boldsymbol{N} z=cBB1N。第7~11行的while循环,在 z − c N ⊤ \boldsymbol{z}-c_{\boldsymbol{N}}^\top zcN中存在正数元素的条件下迭代轴转操作。其中,第8行调用博文《最优化方法Python计算:标准型线性规划的轴转操作》定义的pivot函数,对当前的基矩阵 B \boldsymbol{B} B和非基矩阵 N \boldsymbol{N} N及向量 z \boldsymbol{z} z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值