线性规划单纯形法、大M法,非线性规划的拉格朗日乘子法的手推法,excel、python编程以及python包编程

线性规划单纯形法、大M法,非线性规划的拉格朗日乘子法的手推法,excel、python编程以及python包编程

(1) 线性规划

单纯形法概念

定义

一般线性规划问题中当线性方程组的变量数大于方程个数,这时会有不定数量的解,而单纯形法是求解线性规划问题的通用方法。
具体步骤是,从线性方程组找出一个个的单纯形,每一个单纯形可以求得一组解,然后再判断该解使目标函数值是增大还是变小了,决定下一步选择的单纯形。通过优化迭代,直到目标函数实现最大或最小值。
换而言之,单纯形法就是秉承“保证每一次迭代比前一次更优”的基本思想:先找出一个基本可行解,对它进行鉴别,看是否是最优解;若不是,则按照一定法则转换到另一改进后更优的基本可行解,再鉴别;若仍不是,则再转换,按此重复进行。因基本可行解的个数有限,故经有限次转换必能得出问题的最优解。如果问题无最优解,也可用此法判别。
在这里插入图片描述

标准形式

由于目标函数和约束条件内容和形式上的差别,线性规划问题可以有多种表达式。因此,为了便于讨论和制定统一的算法,在制定单纯形法时,规定使用单纯形法求解的线性规划问题需要有一个标准形式,它有下面三个特征:
(1) 标准形式目标函数统一为求极大值或极小值,但单纯形法主要用来求解极大值;
(2) 所有约束条件(除非负条件外)都是等式,约束条件右端常数项bi全为非负值;
(3) 所有变量的取值全为非负值。
下式为满足上述特征的线性规划问题的标准形式
在这里插入图片描述其中,目标函数中的变量xj(x1,x2,…xn)称为决策变量(控制变量),它的取值受m项资源的限制,它的系数称为价值系数cj。s.t.括号下的内容是约束条件,用bi(i=1,···,m)表示第i种资源的拥有量,用aij表示变量xj取值为1个单位时所消耗或含有的第i种资源的数量,通常称aij为技术系数或工艺系数。
除非负条件外的n个约束条件所组成的n元方程组,若可解可求出n个变量xj的值。求出的n个变量所构成的列向量X=(x1,···xn)T,若能再满足非负条件(即决策变量满足所有约束条件),称为线性规则问题的可行解。使得目标函数值z达到max最大的可行解即为最优解,求解线性规划问题的目的就是要找出目标函数的最优解。
下图为上式标准形式的线性规划问题的展开型:
在这里插入图片描述

步骤

①把线性规划问题的约束方程组表达成典范型方程组,典范型方程组要实现变量转换(所有变量为非负)、目标转换(统一为求极大值,若求极小值可乘以(-1))、约束转换(由不等式转化为等式)。然后,找出基本可行解作为初始基可行解。列出初始单纯形表。
②若基本可行解不存在,即约束条件有矛盾,则问题无解。
③若基本可行解存在,从初始基可行解作为起点,根据最优性条件和可行性条件,引入非基变量取代某一基变量,找出目标函数值更优的另一基本可行解。
④按步骤3进行迭代,直到对应检验数满足最优性条件(这时目标函数值不能再改善),即得到问题的最优解。
⑤若迭代过程中发现问题的目标函数值无界,则终止迭代。

大M法概念

定义

大M法(big M method)是线性规划问题的约束条件(=)等式或(≥)大于型时,使用人工变量法后,寻找其初始基可行解的一种方法
在线性规划问题的约束条件中加人工变量后,要求在目标函数中相应地添加认为的M或一M为系数的项。在极大化问题中,对人工变量赋于一M作为其系数;在极小化问题中,对人工变量赋于一个M作为其系数,M为一任意大(而非无穷大)的正数。把M看作一个代数符号参与运算,用单纯形法求解,故称此方法为大M法
在这里插入图片描述

步骤

应用单纯形法在改进目标函数的过程中,如果原问题存在最优解,必然使人工变量逐步变为非基变量,或使其值为零。否则,目标函数值将不可能达到最小或最大。在迭代过程中,若全部人工变量变成非基变量,则可把人工变量所在的列从单纯形表中删去,此时便找到原问题的一个初始基可行解。若此基可行解不是原问题的最优解,则继续迭代,直至所有的检验数都小于等于0,求得最优解为止

EXCEL求解

下面用到的都是求解这个实例:
在这里插入图片描述

单纯形法

步骤

先输入B2到E9的内容
然后在F2:F5输入下面的算式
F2 =MMULT(B6:D6,F7:F9)
F3 =MMULT(B3:D3,F7:F9)
F4 =MMULT(B4:D4,F7:F9)
F5 =MMULT(B5:D5,F7:F9)
在这里插入图片描述选择工具—规划求解

在这里插入图片描述
设置下面的参数
在这里插入图片描述
设置好之后,选择“选项”,进行配置,弄好之后就可以确定,然后在最初的界面选择“求解”
在这里插入图片描述
就会出现下面的报告

在这里插入图片描述
在这里插入图片描述
在这个运算结果里面可以看到最大值为2,x1=x2=0,x3=2
在这里插入图片描述
在最后的表格中也会看见x1x2x3的值,以及最优解为2

在这里插入图片描述

大M法

步骤
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
按照上述步骤,最终得到的如下:
得到最优解x1=x2=0,x3=2,最优值为2
在这里插入图片描述

Python编程

# encoding=utf-8
import numpy as np  # python 矩阵操作lib
class Simplex():
    def __init__(self):
        self._A = ""  
        self._b = ""  
        self._c = ''  
        self._B = ''  
        self.row = 0  
    def solve(self):
        A = []
        b = []
        c = []
        self._A = np.array(A, dtype=float)
        self._b = np.array(b, dtype=float)
        self._c = np.array(c, dtype=float)
        self._A = np.array([[0,2,-1],[0,1,-1]],dtype=float)
        self._b = np.array([-2,1],dtype=float)
        self._A = np.array([[1,-1,1]])# 等式约束系数self._A,3x1维列向量
        self._b = np.array([2])# 等式约束系数self._b,1x1数值
      
        self._c = np.array([2,1,1],dtype=float)
        self._B = []
        self.row = len(self._b)
        self.var = len(self._c)
        (x, obj) = self.Simplex(self._A, self._b, self._c)
        self.pprint(x, obj, A)
    def pprint(self, x, obj, A):
        px = ['x_%d = %f' % (i + 1, x[i]) for i in range(len(x))]
        print(','.join(px))
        print('objective value is : %f' % obj)
        print('------------------------------')
        for i in range(len(A)):
            print('%d-th line constraint value is : %f' % (i + 1, x.dot(A[i])))
    def InitializeSimplex(self, A, b):
        b_min, min_pos = (np.min(b), np.argmin(b))  # 得到最小bi
        # 将bi全部转化成正数
        if (b_min < 0):
            for i in range(self.row):
                if i != min_pos:
                    A[i] = A[i] - A[min_pos]
                    b[i] = b[i] - b[min_pos]
            A[min_pos] = A[min_pos] * -1
            b[min_pos] = b[min_pos] * -1
        # 添加松弛变量
        slacks = np.eye(self.row)
        A = np.concatenate((A, slacks), axis=1)
        c = np.concatenate((np.zeros(self.var), np.ones(self.row)), axis=0)
        # 松弛变量全部加入基,初始解为b
        new_B = [i + self.var for i in range(self.row)]
        # 辅助方程的目标函数值
        obj = np.sum(b)
        c = c[new_B].reshape(1, -1).dot(A) - c
        c = c[0]
        # entering basis
        e = np.argmax(c)
        while c[e] > 0:
            theta = []
            for i in range(len(b)):
                if A[i][e] > 0:
                    theta.append(b[i] / A[i][e])
                else:
                    theta.append(float("inf"))
            l = np.argmin(np.array(theta))

            if theta[l] == float('inf'):
                print('unbounded')
                return False
            (new_B, A, b, c, obj) = self._PIVOT(new_B, A, b, c, obj, l, e)

            e = np.argmax(c)
 
        for mb in new_B:
            if mb >= self.var:
                row = mb - self.var
                i = 0
                while A[row][i] == 0 and i < self.var:
                    i += 1
                (new_B, A, b, c, obj) = self._PIVOT(new_B, A, b, c, obj, new_B.index(mb), i)
        return (new_B, A[:, 0:self.var], b)
    # 算法入口
    def Simplex(self, A, b, c):
        B = ''
        (B, A, b) = self.InitializeSimplex(A, b)
        # 函数目标值
        obj = np.dot(c[B], b)
        c = np.dot(c[B].reshape(1, -1), A) - c
        c = c[0]
        # entering basis
        e = np.argmax(c)
        # 找到最大的检验数,如果大于0,则目标函数可以优化
        while c[e] > 0:
            theta = []
            for i in range(len(b)):
                if A[i][e] > 0:
                    theta.append(b[i] / A[i][e])
                else:
                    theta.append(float("inf"))
            l = np.argmin(np.array(theta))
            if theta[l] == float('inf'):
                print("unbounded")
                return False
            (B, A, b, c, obj) = self._PIVOT(B, A, b, c, obj, l, e)
            e = np.argmax(c)
        x = self._CalculateX(B, A, b, c)
        return (x, obj)
    # 得到完整解
    def _CalculateX(self, B, A, b, c):
        x = np.zeros(self.var, dtype=float)
        x[B] = b
        return x
    # 基变换
    def _PIVOT(self, B, A, b, c, z, l, e):
        # main element is a_le
        # l represents leaving basis
        # e represents entering basis
        main_elem = A[l][e]
        # scaling the l-th line
        A[l] = A[l] / main_elem
        b[l] = b[l] / main_elem
        # change e-th column to unit array
        for i in range(self.row):
            if i != l:
                b[i] = b[i] - A[i][e] * b[l]
                A[i] = A[i] - A[i][e] * A[l]
        # update objective value
        z -= b[l] * c[e]
        c = c - c[e] * A[l]
        # change the basis
        B[l] = e
        return (B, A, b, c, z)
s = Simplex()
s.solve()

结果如下:
在这里插入图片描述
最终的结果为x1=x2=0,x3=2,最优值为2

Python包编程

#导入包
from scipy import optimize
import numpy as np
#确定c,A,b,Aeq,beq
c = np.array([2,1,1])
A = np.array([[0,2,-1],[0,1,-1]])
b = np.array([-2,1])
Aeq = np.array([[1,-1,1]])
beq = np.array([2])

#求解
res = optimize.linprog(-c,A,b,Aeq,beq,bounds=(x1,x2,x3))
print(res)

结果如下:
在这里插入图片描述
可以看出1.999999…趋近于2,所以最优值近似为2,x1=x2=0,x3=2

通过excel、python编程与python包编程发现,python包求解最为简便,而且通过python包scipy求解做出来的最后的结果值更加的精确

本次实验差不多从excel和python的角度来进行分析求最优解,通过这几个的对比发现,在还是python的包和单纯形法的excel规划求解来的比较的直接,因为都是他们弄好的直接调用包或者是使用工具就可以求出来。但是这些还是需要自己对原理的掌握,才能理解这些的含义,有利于我们更好的学习。

(2)非线性规划

非线性规划的拉格朗日乘子法的Excel,python编码和python包编码

在求取有约束条件的优化问题时,拉格朗日乘子法(LagrangeMultiplier) 和 KKT 条件是非常重要的两个求取方法,对于等式约束的优化问题,可以应用拉 格朗日乘子法去求取最优值;如果含有不等式约束,可以应用 KKT 条件去求取。
当然,这两个方法求得的结果只是必要条件,只有当是凸函数的情况下,才能保 证是充分必要条件。KKT 条件是拉格朗日乘子法的泛化。
【非线性规划问题一般是有约束条件的寻优问题,约束条件可以分成两类:等式约束与不等式约束;也可以将拉格朗日乘子法受约束优化问题转化为无约束优化(与KKT条件)】

等式约束的拉格朗日乘子法

在这里插入图片描述

不等式约束的拉格朗日乘子法

在这里插入图片描述

无约束的拉格朗日乘子法(KKT条件下)

首先将原目标公式和等式不等式合为一个公式
在这里插入图片描述在这里插入图片描述
在进行下面的操作的时候,我们所用到的实例如下:

在这里插入图片描述

手推法

在这里插入图片描述计算如下:
在这里插入图片描述

python包编程

from scipy.optimize import minimize
import numpy as np 
 
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pyplot as plt 
 
#目标函数:
def func(args):
    fun = lambda x: 2*x[0]**2-2*x[0]*x[1]+2*x[1]**2-6*x[0]
    return fun
 
#约束条件,包括等式约束和不等式约束
def con(args):
    cons = ({'type': 'ineq', 'fun': lambda x: 6-3*x[0]-4*x[1]}, #这里的ineq是指大于等于0
            {'type': 'ineq', 'fun': lambda x: x[0]-4*x[1]+2})
    return cons 

if __name__ == "__main__":
    args = ()
    args1 = ()
    cons = con(args1)
    x0 = np.array((1.0, 2.0))  #设置初始值,初始值的设置很重要,很容易收敛到另外的极值点中,建议多试几个值
    
    #求解#
    res = minimize(func(args), x0, method='SLSQP', constraints=cons)
    #####
    print(res.fun)
    print(res.success)
    print(res.x)

在这里插入图片描述

参考文献

1.单纯形法
2.用Excel演示大M单纯形法
3.Python数学模型——线性规划求解(一)
4.非线性优化-拉格朗日乘子法
5.拉格朗日乘子法原理分析
6.python 非线性规划(scipy.optimize.minimize)
7.利用Python求解带约束的最优化问题

人工智能中的优化问题通常可以通过线性规划非线性规划来求解。线性规划是一种优化问题的数学建模方,通过将目标函数和约束条件都表示为线性关系,求解可以使目标函数最大或最小的决策变量的取值。线性规划的一个经典求解方单纯形法单纯形法是一种逐步靠近最优解的迭代算。它从任意可行解开始,通过交替寻找非基变量和基变量,利用单纯形表格进行计算,在每一次迭代中使目标函数达到更优解。这种方适用于线性规划问题,并且在数学理论上能够保证最优解的存在性。 大M法单纯形法的一种改进方,用于处理带有人工变量和松弛变量的问题。通过引入一个大的正数M,将目标函数中的人工变量转化为一个与目标函数无关的惩罚项,从而将问题转化为标准的线性规划问题。大M法可以解决含有无穷边界解或无可行解的线性规划问题。 非线性规划是指目标函数或约束条件中存在非线性项的优化问题。对于非线性规划问题,可以使用拉格朗日乘子法进行求解。拉格朗日乘子法通过构建拉格朗日函数来将非线性约束转化为等式约束,从而将非线性规划问题转化为无约束问题。通过求解拉格朗日函数的稳定点,可以得到原始非线性规划问题的解。 总而言之,线性规划是一种用于求解目标函数和约束条件都具有线性关系的优化问题的方单纯形法大M法线性规划的两种常用解非线性规划则用于处理目标函数或约束条件中存在非线性项的优化问题,拉格朗日乘子法是一种求解非线性规划问题的常用方
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值