数学建模系列文章:
以下是个人在准备数模国赛时候的一些模型算法和代码整理,有空会不断更新内容:
评价模型(一)层次分析法(AHP),熵权法,TOPSIS分析 及其对应 PYTHON 实现代码和例题解释
评价模型(二)主成分分析、因子分析、二者对比及其对应 PYTHON 实现代码和例题解释
优化模型(零)总述,分类,解析各类优化模型及普适做题步骤
优化模型(一)线性规划详解,以及例题,用python的Pulp库函数求解线性规划
优化模型(二)非线性规划详解,以及例题,Scipy.optimize 求解非线性规划
3.2 线性规划 Pulp库函数求解
关于优化问题的基础知识,看概述
线性规划定义:
如果目标函数f(x)和约束条件均是决策变量的线性表达式,那此时的数学规划问题属于线性规划,线性规划问题用python的 pulp库求解更为便捷,如果是非线性函数一般用
scipy.optimize
求解
PuLP 库求解线性规划
PuLP是一个开源的第三方工具包,可以求解线性规划、整数规划、混合整数规划问题。
下面先介绍一下Pulp一些基础的库函数,再以一些例题为例进行重复讲解
基本的一些函数定义:
pulp.LpProblem("LPProbDemo1", sense=pulp.LpMaximize)
pulp.LpProblem
是定义问题的构造函数。
LPProbDemo1
是用户定义的问题名(用于输出信息)。
sense
用来指定求最小值/最大值问题,可选参数值:LpMinimize、LpMaximize
x1 = pulp.LpVariable('x1', lowBound=0, upBound=7, cat='Continuous')
x1
是用户定义的变量名
lowBound、upBound
用来设定决策变量的下界、上界;可以不定义下界/上界,默认的下界/上界是负无穷/正无穷。本例中 x1,x2,x3 的取值区间为 [0,7]。
cat
用来设定变量类型,可选参数值:
- ‘Continuous’ 表示连续变量(默认值)、
- ’Integer ’ 表示离散变量(用于整数规划问题)、
- ’Binary ’ 表示0/1变量(用于0/1规划问题)。
pulp.value(MyProbLP.objective)
目标函数的最值,即结果
pulp.LpStatus[MyProbLP.status]
输出求解状态如果 是 Status: Optimal 是合理的状态
例题1 一个简单的求解线性规划问题
max fx = 2*x1 + 3*x2 - 5*x3
s.t. x1 + 3*x2 + x3 <= 12
2*x1 - 5*x2 + x3 >= 10
x1 + x2 + x3 = 7
x1, x2, x3 >=0
求解代码:
# 导入 PuLP库函数
import pulp
# 定义一个规划问题
MyProbLP = pulp.LpProblem("LPProbDemo1", sense=pulp.LpMaximize)
'''
pulp.LpProblem 是定义问题的构造函数。
"LPProbDemo1"是用户定义的问题名(用于输出信息)。
sense 用来指定求最小值/最大值问题,可选参数值:LpMinimize、LpMaximize 。
'''
# 定义决策变量
x1 = pulp.LpVariable('x1', lowBound=0, upBound=7, cat='Continuous')
x2 = pulp.LpVariable('x2', lowBound=0, upBound=7, cat='Continuous')
x3 = pulp.LpVariable('x3', lowBound=0, upBound=7, cat='Continuous')
'''
pulp.LpVariable 是定义决策变量的函数。
‘x1’ 是用户定义的变量名。
参数 lowBound、upBound 用来设定决策变量的下界、上界;可以不定义下界/上界,默认的下界/上界是负无穷/正无穷。本例中 x1,x2,x3 的取值区间为 [0,7]。
参数 cat 用来设定变量类型,可选参数值:
‘Continuous’ 表示连续变量(默认值)、
’Integer ’ 表示离散变量(用于整数规划问题)、
’Binary ’ 表示0/1变量(用于0/1规划问题)。
'''
MyProbLP += 2*x1 + 3*x2 - 5*x3 # 设置目标函数
MyProbLP += (2*x1 - 5*x2 + x3 >= 10) # 不等式约束
MyProbLP += (x1 + 3*x2 + x3 <= 12) # 不等式约束
MyProbLP += (x1 + x2 + x3 == 7) # 等式约束
MyProbLP.solve()
# 输出求解状态
print("Status:", pulp.LpStatus[MyProbLP.status])
# 输出每个变量的最优值
for v in MyProbLP.variables():
print(v.name, "=", v.varValue)
# 输出最优解的目标函数值
print("F(x) = ", pulp.value(MyProbLP.objective))
# 输出结果如下
'''
Optimal - objective value 14.571429
Optimal objective 14.57142857 - 2 iterations time 0.002
Option for printingOptions changed from normal to all
Total time (CPU seconds): 0.00 (Wallclock seconds): 0.00
Status: Optimal
x1 = 6.4285714
x2 = 0.57142857
x3 = 0.0
F(x) = 14.57142851
'''
线性规划例题2(源自清风建模课件)
求解代码:
# 公式就是图上的公式
import pulp
MyProbLP = pulp.LpProblem("LPProbDemo1", sense=pulp.LpMaximize)
# 定义整型变量 'Integer' 范围是(0,+inf)
x1 = pulp.LpVariable('x1', lowBound=0, cat='Integer')
x2 = pulp.LpVariable('x2', lowBound=0, cat='Integer')
x3 = pulp.LpVariable('x3', lowBound=0, cat='Integer')
x4 = pulp.LpVariable('x4', lowBound=0, cat='Integer')
x5 = pulp.LpVariable('x5', lowBound=0, cat='Integer')
x6 = pulp.LpVariable('x6', lowBound=0, cat='Integer')
x7 = pulp.LpVariable('x7', lowBound=0, cat='Integer')
x8 = pulp.LpVariable('x8', lowBound=0, cat='Integer')
x9 = pulp.LpVariable('x9', lowBound=0, cat='Integer')
# 设置目标函数
MyProbLP += 1*(x1+x2) + 1.65*x8 + 2.3*x9 - 0.05*(5*x1+10*x6)-0.0321*(7*x2+9*x7+12*x9)-0.0625*(6*x3+8*x8)-0.111857*(4*x4+11*x9)-0.05*7*x5
# 设置约束函数
MyProbLP += (5*x1 + 10*x6 <= 6000) # 不等式约束
MyProbLP += (7*x2+9*x7+12*x9 <= 10000) # 不等式约束
MyProbLP += (6*x3+8*x8 <= 4000) # 不等式约束
MyProbLP += (4*x4+11*x9 <= 7000) # 不等式约束
MyProbLP += (7*x5 <= 4000) # 不等式约束
MyProbLP += (x1 + x2 == x3 + x4 + x5) # 等式约束
MyProbLP += (x6 + x7 == x8) # 等式约束
MyProbLP.solve()
# 输出求解状态
print("Status:", pulp.LpStatus[MyProbLP.status])
# 输出每个变量的最优值
for v in MyProbLP.variables():
print(v.name, "=", v.varValue)
#输出最优解的目标函数值
print("F(x) = ", pulp.value(MyProbLP.objective))
输出结果
'''
Status: Optimal
x1 = 1200.0
x2 = 230.0
x3 = 0.0
x4 = 859.0
x5 = 571.0
x6 = 0.0
x7 = 500.0
x8 = 500.0
x9 = 324.0
F(x) = 1146.4152
'''