基于jupyter notebook的python编程-----通过单纯形法和scipy库对比分析求解线性规划最大值和最优解问题


在进行人工智能机器学习时候,算法是解决机器快速数据处理的一个重要因素,而对线性回归分析最为重要,前面林君学长也介绍了很多种对线性回归分析的求解方法,今天,林君学长将带大家了解如何通过单纯形法和python的scipy库来进行线性分析求解,下面的过程将以林君学长给出的例子为例

一、单纯形法的简单了解

1、单纯形法的定义

1)、单纯形法 simplex method 求解线性规划问题的通用方法。单纯形是美国数学家G.B.丹齐克于1947年首先提出来的。它的理论根据是:线性规划问题的可行域是 n维向量空间Rn中的多面凸集,其最优值如果存在必在该凸集的某顶点处达到。顶点所对应的可行解称为基本可行解。

2、单纯形法的基本思路

1)、单纯形法的基本思想是:先找出一个基本可行解,对它进行鉴别,看是否是最优解;若不是,则按照一定法则转换到另一改进的基本可行解,再鉴别;若仍不是,则再转换,按此重复进行。因基本可行解的个数有限,故经有限次转换必能得出问题的最优解。如果问题无最优解也可用此法判别。 根据单纯形法的原理,在线性规划问题中,决策变量(控制变量)x1,x2,…x n的值称为一个解,满足所有的约束条件的解称为可行解。使目标函数达到最大值(或最小值)的可行解称为最优解。这样,一个最优解能在整个由约束条件所确定的可行区域内使目标函数达到最大值(或最小值)。求解线性规划问题的目的就是要找出最优解。

3、单纯形法的解题步骤

1)、把线性规划问题的约束方程组表达成典范型方程组,找出基本可行解作为初始基本可行解。
2)、若基本可行解不存在,即约束条件有矛盾,则问题无解。
3)、若基本可行解存在,从初始基本可行解作为起点,根据最优性条件和可行性条件,引入非基变量取代某一基变量,找出目标函数值更优的另一基本可行解
4)、按步骤3进行迭代,直到对应检验数满足最优性条件(这时目标函数值不能再改善),即得到问题的最优解。
5)、若迭代过程中发现问题的目标函数值无界,则终止迭代。

用单纯形法求解线性规划问题所需的迭代次数主要取决于约束条件的个数。现在一般的线性规划问题都是应用单纯形法标准软件在计算机上求解,对于具有106个决策变量和104个约束条件的线性规划问题已能在计算机上解得。

4、最优解可能出现的情况

1)、存在着一个最优解
2)、存在着无穷多个最优解
3)、不存在最优解

不存在最优解只在两种情况下发生,即没有可行解或各项约束条件不阻止目标函数的值无限增大(或向负的方向无限增大)

下面,林君学长通过例题向大家进行解答:

二、例题

1、求解以下约束条件的线性规划的最大值和最优解

1)、题目
在这里插入图片描述
以上题目,给出了线性规划的约束条件,所以我们可以通过这个进行对应的最优值和最大值的求解分析

2、求解思路

1)、线性规范-标准化
以上题目的规范化如下所示:
引入松弛变量:s1,s2,s3
在这里插入图片描述
2)、提取系数,填入表格
在这里插入图片描述
上面区域解答如下:
在这里插入图片描述
其中,s1、s2、s3作为基
在这里插入图片描述
3)、接下来就是通过原理求解啦
从初始基本可行解X0迭代出另一个基本可行解X1,并判断X1是否
为最优解。
在这里插入图片描述
从一个基本可行解迭代出另一个基本可行解可分为两步进行:
第一步,从原来的非基变量中选一个(称为进基变量)使其成为基本变量;
第二步,从原来的基本变量中选一个(称为离基变量)使其成为新的非基变量,最终便可求得答案!具体参考文档求解:
https://wenku.baidu.com/view/5a9139bb3069a45177232f60ddccda38366be10f.html

3、该题答案

1)、通过手工推导,上面的最优解为Z=27500
2)、最优解为
X1=50
X2=250
S1=50
s2=s3=0
上面为最终结果,接下来,林君学长将带大家通过两种方法进行求解

三、通过单纯形法求解线性规划最优解和最大值

1、搭建python环境

1)、打开Windows终端命令行,输入jupyter notebook,打开我们的jupyter工具,如下所示:
在这里插入图片描述
2)、在jupyter的web网页中创建python文件,如下所示:
在这里插入图片描述
3)、现在就可以在jupyter的代码行里面输入我们的代码啦!

2、新建txt文档,填入线性回归分析标准化模型

1)、题目中的线性回归分析的标准化模型如下:
在这里插入图片描述
2)、新建txt文档,写入标准化模型系数,如下所示:

50 100   0   0   0   0
1   1    1   0   0   300
2   1    0   1   0   400
0   1    0   0   1   250

在这里插入图片描述

3、编写python代码

1)、导入需要的库

import numpy as np

2)、定义列出线性回归系数模型函数

def pivot(d,bn):
    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]))  #转出下标
    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]        

2)、定义更新基变量函数:从一个初始极点出发,不断找到更优的相邻极点,直到找到最优的极点(或极线)

def solve(d,bn):
    flag = True
    while flag:
        if max(list(d[0][:-1])) <= 0: #直至所有系数小于等于0
            flag = False
        else:
            pivot(d,bn)      

3)、定义输出打印结果函数

def printSol(d,cn):
    for i in range(cn - 1):
        if i in s:
            print("x"+str(i)+"=%.2f" % d[s.index(i)+1][-1])
        else:
            print("x"+str(i)+"=0.00")
    print("objective is %.2f"%(-d[0][-1]))

4)、导入线性回归模型、调用函数,求解最优解和最优值

d = np.loadtxt("D:\\my.txt", dtype=np.float)
(bn,cn) = d.shape
s = list(range(cn-bn,cn-1)) #基变量列表
solve(d,bn)
printSol(d,cn)

运行结果如下所示:
在这里插入图片描述
上图中,x2、x3、x4对应引入的变量 s1、s2、s3

4、python整体代码如下所示:

import numpy as np
def pivot(d,bn):
    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]))  #转出下标
    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(d,bn):
    flag = True
    while flag:
        if max(list(d[0][:-1])) <= 0: #直至所有系数小于等于0
            flag = False
        else:
            pivot(d,bn)            
def printSol(d,cn):
    for i in range(cn - 1):
        if i in s:
            print("x"+str(i)+"=%.2f" % d[s.index(i)+1][-1])
        else:
            print("x"+str(i)+"=0.00")
    print("objective is %.2f"%(-d[0][-1]))
d = np.loadtxt("D:\\my.txt", dtype=np.float)
(bn,cn) = d.shape
s = list(range(cn-bn,cn-1)) #基变量列表
solve(d,bn)
printSol(d,cn)

四、通过python中的scipy库对线性规划的最优解、最大值进行求解

1、通过scipy库比较简单,这里直接给出完整代码

1)、根据模型填写系数。线性回归模型如下:
在这里插入图片描述
1)、代码如下所示:

#导入包
from scipy import optimize
import numpy as np
#确定c,A_ub,B_ub
c = np.array([50,100])
A_ub = np.array([[1,1],[2,1],[0,1]])
B_ub = np.array([300,400,250])
#求解
res =optimize.linprog(-c,A_ub,B_ub)
print(res)

2)、代码说明
很容易发现:
c:c指的应该是要求最大值的函数的系数数组
A_ub:A_ub是应该是不等式未知量的系数矩阵,也就是不等式左边
B_ub:B_ub就是不等式的右边了,也就是不等式右边

需要注意的是:如果大家的题目中,不等式方向不一样,需要添加负号调节方向,使之对应;相应的,系数矩阵的系数也要改变方向!

2、运行结果

1)、运行结果如下所示:
在这里插入图片描述
以上结果,第二行的绝对值表示最优值,也就是最大值,最后一行表示最优解,也就是x1、x2!

3、以上两种方法对的结果对比分析

1)、单纯形法结果:
在这里插入图片描述
2)、scipy库结果:
在这里插入图片描述
通过以上两种结果对比,以精确度来说,单纯形法的结果更加精确,因为是具体结果x0=50,x1=250;相比于scipy库来说,更加精确,对于scipy库的内部方法,我们不得而知,但从结果来看,不应该是小数,而是整体结果,手工推导也是如此,但相差不大,基本误差在0.00000001,所以,这个误差可以忽略!
以上就是本次博客的全部内容啦,希望对阅读的小伙伴理解单纯形法和scipy库的求解线性规划有一定的了解
遇到问题的小伙伴记得评论区留言、林君学长看到会为大家解答的哦!

陈一月的又一天编程岁月^ _ ^

发布了81 篇原创文章 · 获赞 119 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_42451251/article/details/105597806
今日推荐