线性规划(Linear programming,简称LP),是运筹学中研究较早、发展较快、应用广泛、方法较成熟的一个重要分支,它是辅助人们进行科学管理的一种数学方法。研究线性约束条件下线性目标函数的极值问题的数学理论和方法。英文缩写LP。线性规划是运筹学的一个重要分支,广泛应用于军事作战、经济分析、经营管理和工程技术等方面。为合理地利用有限的人力、物力、财力等资源作出的最优决策,提供科学的依据。
数学模型:
(1)列出约束条件及目标函数
(2)画出约束条件所表示的可行域
(3)在可行域内求目标函数的最优解及最优值
描述线性规划问题的标准形式:
线性规划步骤:
一般线性规划问题中当线性方程组的变量数大于方程个数,这时会有不定数量的解,而单纯形法是求解线性规划问题的通用方法。具体步骤是,从线性方程组找出一个个的单纯形,每一个单纯形可以求得一组解,然后再判断该解使目标函数值是增大还是变小了,决定下一步选择的单纯形。通过优化迭代,直到目标函数实现最大或最小值。换而言之,单纯形法就是秉承“保证每一次迭代比前一次更优”的基本思想:先找出一个基本可行解,对它进行鉴别,看是否是最优解;若不是,则按照一定法则转换到另一改进后更优的基本可行解,再鉴别;若仍不是,则再转换,按此重复进行。因基本可行解的个数有限,故经有限次转换必能得出问题的最优解。如果问题无最优解,也可用此法判别。
算法效率:
在采用Bland’s法则选择用于转轴操作的d和e(相同值的情况下取字典序最小)之后,可以证明单纯形法一定能够在有限步之后终止,但是最坏情况算法的时间复杂度为指数级别的,而且可以构造出让单纯形法的时间复杂度达到指数级别的具体实例。不过实践证明在绝大多数情况下单纯形法的效率非常令人满意。单纯形法的最坏时间复杂度为指数级别,并不意味着线性规划不存在多项式级别的算法。椭球算法和内点算法均为解决线性规划的多项式时间算法。
大M法(big M method)是线性规划问题的约束条件(=)等式或(≥)大于型时,使用人工变量法后,寻找其初始基可行解的一种方法。在线性规划问题的约束条件中加人工变量后,要求在目标函数中相应地添加认为的M或一M为系数的项。在极大化问题中,对人工变量赋于一M作为其系数;在极小化问题中,对人工变量赋于一个M作为其系数,M为一任意大(而非无穷大)的正数。把M看作一个代数符号参与运算,用单纯形法求解,故称此方法为大M法。
求解步骤:应用单纯形法在改进目标函数的过程中,如果原问题存在最优解,必然使人工变量逐步变为非基变量,或使其值为零。否则,目标函数值将不可能达到最小或最大。在迭代过程中,若全部人工变量变成非基变量,则可把人工变量所在的列从单纯形表中删去,此时便找到原问题的一个初始基可行解。若此基可行解不是原问题的最优解,则继续迭代,直至所有的检验数都小于等于0,求得最优解为止。
非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。对于一个实际问题,在把它归结成非线性规划问题时,一般要注意如下几点 :
(i)确定供选方案:首先要收集同问题有关的资料和数据,在全面熟悉问题的基础上,确认什么是问题的可供选择的方案,并用一组变量来表示它们。
(ii)提出追求目标:经过资料分析,根据实际需要和可能,提出要追求极小化或极大化的目标。并且,运用各种科学和技术原理,把它表示成数学关系式。
(iii)给出价值标准:在提出要追求的目标之后,要确立所考虑目标的“好”或“坏”的价值标准,并用某种数量形式来描述它。
(iv)寻求限制条件:由于所追求的目标一般都要在一定的条件下取得极小化或极大化效果,因此还需要寻找出问题的所有限制条件,这些条件通常用变量之间的一些不等式或等式来表示。
在数学最优问题中,拉格朗日乘数法(以数学家约瑟夫·路易斯·拉格朗日命名)是一种寻找变量受一个或多个条件所限制的多元函数的极值的方法。这种方法将一个有n 个变量与k 个约束条件的最优化问题转换为一个有n + k个变量的方程组的极值问题,其变量不受任何约束。这种方法引入了一种新的标量未知数,即拉格朗日乘数:约束方程的梯度(gradient)的线性组合里每个向量的系数。此方法的证明牵涉到偏微分,全微分或链法,从而找到能让设出的隐函数的微分为零的未知数的值。
excel中求解:
具体求解过程见:https://download.csdn.net/download/weixin_43709601/12343426
Python求解:
#导入包
from scipy import optimize
import numpy as np
#确定c,A,b,Aeq,beq
c = np.array([115,90])
A = np.array([[10,20],[4,16],[15,10]])
b = np.array([200,128,220])
#Aeq = np.array([[1,-1,1]])
#beq = np.array([2])
#求解
res = optimize.linprog(-c,A,b)
print(res)
con: array([], dtype=float64)
fun: -1739.9998980068146
message: 'Optimization terminated successfully.'
nit: 4
slack: array([1.21961204e-05, 1.60000071e+01, 1.28281521e-05])
status: 0
success: True
x: array([11.99999933, 3.99999973])
python代码运行结果中第二行的值去掉负号就是目标函数的最大值,最后一行就是函数的最优解,由此可知,最大值约为1740,x≈12.0,y≈4.0。
利用excel的规划求解包求解和Python代码相关库求解的结果差不多,只不过利用Python代码求解的结果更加精确。
excel中求解:
具体求解过程请见:https://download.csdn.net/download/weixin_43709601/12343665
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)
print(res)
con: array([8.49542658e-12])
fun: -2.00000000002079
message: 'Optimization terminated successfully.'
nit: 4
slack: array([-2.64934741e-11, 3.00000000e+00])
status: 0
success: True
x: array([6.71064802e-12, 1.12873931e-11, 2.00000000e+00])
由此可知,在excel中求得最优值为2,最优解x1=x2=0,x3=2;python代码相关库求得最优值约为2.00,最优解x1≈x2≈0,x3=2.00
手工推导过程:
Python代码:这里只考虑有约束的情况,假设a=b=c=1,求目标函数的最大值和最优解。
from scipy.optimize import minimize
import numpy as np
e = 1e-10 # 非常接近0的值
fun = lambda x : 8 * (x[0] * x[1] * x[2]) # 约束函数f(x,y,z) =8 *x*y*z
cons = ({'type': 'eq', 'fun': lambda x: x[0]**2+ x[1]**2+ x[2]**2 - 1}, # x^2 + y^2 + z^2=1
{'type': 'ineq', 'fun': lambda x: x[0] - e}, # x>=e,即 x > 0
{'type': 'ineq', 'fun': lambda x: x[1] - e},
{'type': 'ineq', 'fun': lambda x: x[2] - e}
)
x0 = np.array((1.0, 1.0, 1.0)) # 设置初始值
res = minimize(fun, x0, method='SLSQP', constraints=cons)
print('最大值:',res.fun)
print('最优解:',res.x)
print('迭代终止是否成功:', res.success)
print('迭代终止原因:', res.message)
最大值: 1.5396007243645415
最优解: [0.57735022 0.57735022 0.57735038]
迭代终止是否成功: True
迭代终止原因: Optimization terminated successfully.
由此可知,手工推导出来的结果和Python代码推出来的结果一样。要检验解是否为最优解就要用KKT条件。将所得解代入g(x,y,z)等于0,将所得解代入各自的对L的偏导也等于0,满足KKT条件,所以是最优解。