线性规划Python实现:使用库函数和不使用库函数进行单纯形法(大M法)线性规划

使用库函数和不使用库函数进行单纯形法(大M法)线性规划

    • 单纯形法的原理
    • 使用scipy库进行单纯形法线性规划
    • 不使用库函数进行单纯形法线

单纯形法的原理

可以参考:线性规划之单纯形法【超详解+图解】.
大M法(big M method)是线性规划问题的约束条件(=)等式或(≥)大于型时,使用人工变量法后,寻找其初始基可行解的一种方法。
应用单纯形法在改进目标函数的过程中,如果原问题存在最优解,必然使人工变量逐步变为非基变量,或使其值为零。否则,目标函数值将不可能达到最小或最大。在迭代过程中,若全部人工变量变成非基变量,则可把人工变量所在的列从单纯形表中删去,此时便找到原问题的一个初始基可行解。若此基可行解不是原问题的最优解,则继续迭代,直至所有的检验数都小于等于0,求得最优解为止。(来源百度百科)
用单纯形法求解线性规划要先将线性规划变为标准形式,然后添加人工变量进行求解
max 2 x 1 + x 2 + x 3 2x_1+x_2+x_3 2x1+x2+x3
s . t = { − 2 x 2 ≥ 2 x 1 − x 2 + x 3 = 2 x 2 − x 3 ≤ 1 x 1 , x 2 , x 3 ≥ 0 s.t=\begin{cases} -2x_2\geq 2 \\\\ x_1-x_2+x_3= 2 \\\\ x_2-x_3\leq 1 \\\\ x_1,x_2,x_3\geq0 \end{cases} s.t=2x22x1x2+x3=2x2x31x1,x2,x30
变为标准形式
max 2 x 1 + x 2 + x 3 + 0 x 4 + 0 x 5 2x_1+x_2+x_3+0x4+0x5 2x1+x2+x3+0x4+0x5
s . t = { − 2 x 2 − x 4 = 2 x 1 − x 2 + x 3 = 2 x 2 − x 3 + x 5 = 1 x 1 , x 2 , x 3 ≥ 0 s.t=\begin{cases} -2x_2-x4= 2 \\\\ x_1-x_2+x_3= 2 \\\\ x_2-x_3+x5= 1 \\\\ x_1,x_2,x_3\geq0 \end{cases} s.t=2x2x4=2x1x2+x3=2x2x3+x5=1x1,x2,x30
加入人工变量:
max 2 x 1 + x 2 + x 3 + 0 x 4 + 0 x 5 − M x 6 − M x 7 2x_1+x_2+x_3+0x4+0x5-Mx6-Mx7 2x1+x2+x3+0x4+0x5Mx6Mx7
s . t = { − 2 x 2 − x 4 = 2 x 1 − x 2 + x 3 + x 5 + x 6 = 2 x 2 − x 3 + x 6 + x 7 = 1 x 1 , x 2 , x 3 ≥ 0 s.t=\begin{cases} -2x_2-x4= 2 \\\\ x_1-x_2+x_3+x5+x6= 2 \\\\ x_2-x_3+x6+x7= 1 \\\\ x_1,x_2,x_3\geq0 \end{cases} s.t=2x2x4=2x1x2+x3+x5+x6=2x2x3+x6+x7=1x1,x2,x30
M是一个任意值的正数
根据上述方程组可以得到初始的基可行解,列出初始单纯形表
线性规划Python实现:使用库函数和不使用库函数进行单纯形法(大M法)线性规划_第1张图片
进行单纯形法迭代计算,根据检验数系数是否有正数,来判断是否要换基,然后又求检验数系数,判断是否换基,直到校验系数区没有正数时,若是基变量中含有非零的人工变量,则没有可行解,否则就有最优解

使用scipy库进行单纯形法线性规划

给出的线性规划为:max 2 x 1 + x 2 + x 3 2x_1+x_2+x_3 2x1+x2+x3
s . t = { − 2 x 2 ≥ 2 x 1 − x 2 + x 3 = 2 x 2 − x 3 ≤ 1 x 1 , x 2 , x 3 ≥ 0 s.t=\begin{cases} -2x_2\geq 2 \\\\ x_1-x_2+x_3= 2 \\\\ x_2-x_3\leq 1 \\\\ x_1,x_2,x_3\geq0 \end{cases} s.t=2x22x1x2+x3=2x2x31x1,x2,x30

import numpy as np
from scipy.optimize import linprog 

a = np.array([2,1,1])#函数未知数的系数
A_ub = np.array([[0,2,-1],[0,1,-1]])#不等式约束变换为<=之后的系数
b_ub = np.array([-2,1])#为不等式约束的常数
A_eq = np.array([[1,-1,1]])#等式约束的系数
b_eq = np.array([2])#等式约束的常数
s = linprog(a,A_ub,b_ub,A_eq,b_eq,bounds=((0,None),(0,None),(0,None)))
print(s)

得到的结果:最优值为1.999999, x 1 = 0 , x 2 = 0 , x 3 = 2 x_1=0,x_2=0,x_3=2 x1=0,x2=0,x3=2
线性规划Python实现:使用库函数和不使用库函数进行单纯形法(大M法)线性规划_第2张图片
当然进行函数运行时,提前要检验是否有最优解。

不使用库函数进行单纯形法线

这个就比较难了就要先验证是否有最优解,然后才能通过程序进行运算。如果一个线性规划没有最优解,程序就会陷入死循环,不能得出运行结果。
给出的线性规划为:max z = 4 x 1 + 3 x 2 z = 4x_1+3x_2 z=4x1+3x2
s . t = { x 1 ≤ 6 2 x 2 ≤ 8 2 x 1 + 3 x 2 ≤ 18 x 1 , x 2 ≥ 0 s.t=\begin{cases} x1\leq 6 \\\\ 2x2\leq 8 \\\\ 2x1+3x2\leq 18 \\\\ x1,x2\geq0 \\\\ \end{cases} s.t=x162x282x1+3x218x1,x20
加入松弛变量后
max z = 4 x 1 + 3 x 2 + 0 x 3 + 0 x 4 + 0 x 5 z = 4x1+3x2+0x3+0x4+0x5 z=4x1+3x2+0x3+0x4+0x5
s . t = { x 1 + x 3 = 6 2 x 2 + x 4 = 8 2 x 1 + 3 x 2 + x 5 = 18 x 1 , x 2 ≥ 0 s.t=\begin{cases} x1+x3=6 \\\\ 2x2+x4= 8 \\\\ 2x1+3x2+x5=18 \\\\ x1,x2\geq0 \end{cases} s.t=x1+x3=62x2+x4=82x1+3x2+x5=18x1,x20
根据约束条件和函数,可以看出函数是有最优解的:
线性规划Python实现:使用库函数和不使用库函数进行单纯形法(大M法)线性规划_第3张图片
data.text中所存放的数据为
线性规划Python实现:使用库函数和不使用库函数进行单纯形法(大M法)线性规划_第4张图片

import numpy as np

def pivot():
    l = list(d[0][:-2])
    jnum = l.index(max(l)) #转入编号
    m = []
    for i in range(bn):
        if d[i][jnum] == 0:
            m.append(0.)
        else:
            m.append(d[i][-1]/d[i][jnum])
    inum = m.index(min([x for x in m[1:] if x!=0]))  #转出下标
    print("下标",inum)
    s[inum-1] = jnum
    r = d[inum][jnum]
    d[inum] /= r
    for i in [x for x in range(bn) if x !=inum]:
        r = d[i][jnum]
        d[i] -=r * d[inum]
        
def solve():
    flag = True
    while flag:
        if max(list(d[0][:-1])) <= 0: #直至所有系数小于等于0
            flag = False
        else:
            pivot()
            
def printSol():
    for i in range(cn - 1):
        if i in s:
            print("x"+str(i+1)+"=%.2f" % d[s.index(i)+1][-1])
        else:
            print("x"+str(i+1)+"=0.00")
    print("objective is %.2f"%(-d[0][-1]))
d = np.loadtxt("data.txt", dtype=np.float)
(bn,cn) = d.shape
s = list(range(cn-bn,cn-1)) #基变量列表
solve()
printSol()

结果显示为:
线性规划Python实现:使用库函数和不使用库函数进行单纯形法(大M法)线性规划_第5张图片
而对于最优解的线性规划:
给出的线性规划为:max z = x 1 + x 2 z = x_1+x_2 z=x1+x2
s . t = { 2 x 1 − x 2 ≥ 3 x 1 − 2 x 2 ≤ 4 x 1 + x 2 ≥ 12 x 1 , x 2 ≥ 0 s.t=\begin{cases} 2x1-x2\geq 3 \\\\ x1-2x2\leq 4 \\\\ x1+x2\geq12 \\\\ x1,x2\geq0 \end{cases} s.t=2x1x23x12x24x1+x212x1,x20
加入松弛变量后:max z = x 1 + x 2 + 0 x 3 + 0 x 4 z = x_1+x_2+0x3+0x4 z=x1+x2+0x3+0x4
s . t = { − 2 x 1 + x 2 + x 3 = 3 x 1 − 2 x 2 + x 4 = 4 x 1 + x 2 = 12 x 1 , x 2 , x 3 , x 4 ≥ 0 s.t=\begin{cases} -2x1+x2+x3= 3 \\\\ x1-2x2+x4=4 \\\\ x1+x2=12 \\\\ x1,x2,x3,x4\geq0 \end{cases} s.t=2x1+x2+x3=3x12x2+x4=4x1+x2=12x1,x2,x3,x40
图中显示若是添加一个限制条件x1+x2>12,就不存在最优解
线性规划Python实现:使用库函数和不使用库函数进行单纯形法(大M法)线性规划_第6张图片
data1.text文件中的数据为:
线性规划Python实现:使用库函数和不使用库函数进行单纯形法(大M法)线性规划_第7张图片
程序运行的结果为:一直输出下标,说明一直在换基
线性规划Python实现:使用库函数和不使用库函数进行单纯形法(大M法)线性规划_第8张图片
但是我用scipy库的代码进行运算的时候,得出的结果是有值输出,我不理解:
线性规划Python实现:使用库函数和不使用库函数进行单纯形法(大M法)线性规划_第9张图片
有知道的路过的大佬,方便的话告诉我一下。
如有错误请指正!
代码参考:线性规划:单纯形法python代码.

你可能感兴趣的:(人工智能)