【写在前面】本篇文章主要英语运筹学基础教学,主要实现目标是“能算”,一些更深层次的问题不作讨论(遇到再说)
搞目标规划之前应该了解线性规划,线性规划这里就不再赘述了
用optimize 和 numpy 模块就可以实现(这里只考虑简单的求解问题)
随便举个例子就过了,线性规划三要素 目标 约束 和变量
变量为正即可[0,np.inf]
目标函数的系数用c来表示,默认求min,加负号求max
A是约束条件系数
b是约束条件限值
ub表示不等式约束 默认小于等于,大于等于两边加负号
eq表示等式约束
from scipy import optimize as op
import numpy as np
c = np.array([-2, -3, 5])
A_ub = np.array([[-2, 5, -1], [1, 3, 1]])
b_ub = np.array([-10, 12])
A_eq = np.array([[1, 1, 1]])
b_eq = np.array([7])
x1 = [0, np.inf]
x2 = [0, np.inf]
x3 = [0, np.inf]
res = op.linprog(c, A_ub, b_ub, A_eq, b_eq, bounds=(x1, x2, x3)) # bounds为每个为每个未知量的范围
print(res)
下面讲目标规划,也有叫多目标优化的
解决问题一般也是带线性约束条件的优化问题
线性规划的约束比较硬,我们就叫他 “硬约束”
比如:
【苹果不能少于5个 鸭梨不能少于3个 总共水果必须是10个】
巴拉巴拉这样的约束,听起来就很生硬,提出这样要求的小朋友在幼儿园可能不太讨喜
换个方式,软一点,要求放松一点应该会好些
【苹果争取多于5个 鸭梨争取多于3个 总共水果最好是10个】
看这样的语气就卑微了一些,也让人舒服了一点
当然,放松要求不是降低要求,小朋友应该有自己的大局观
放松要求的目的是保证自己的关键利益
可能小朋友爱吃苹果,那苹果就的约束就是最优先
可能小朋友对吃水果的数量有要求,那总数的约束就作为最优先
目标规划可以把这个问题根据自己制定的优先等级,得到一个具有大局观的最优解。
目标规划 的关键词 包括 【硬约束】【软约束】【偏差变量】【优先级】【权因子】【达成函数】,大家可以自行了解
最终的标准形式就是
可以用序贯法求解目标规划
序贯法求解的主要思路就是,把问题按层级进行计算,由高到低,算第一层就只关注第一层的偏差变量
比如说这样一个表达式
第一层级的问题就是
min d1-
与它有关的约束就是
那么第一层的子问题数学模型就是
min d1-
下面用Python的linprog()计算第一层级
出现了问题 结果和书上的不太一样 lingo计算的不对
python更不对 出现了很多虚数
python没太搞懂先用lingo实现一下
可以一开始就把所有约束列出来,反正无关的算了也没关系
只是改变目标函数即可
min d1_
s.t.
2x1+2x2<=12
200x1+300x2+d1_-d1=1500
2x1-x2+d2_-d2=0
4x1+d3_-d3=16
5x2+d4_-d4=15
代码中用d1_来表示d1- ;d1来表示d1
第一层优化结果为
d1_=0;
直接带进去计算下一层级
算完了发现可以直接把之前的目标函数注释掉,再把结果放进去即可
!min d1_!第一层目标函数
!min d2+d2_!第二层目标函数
min 3d3+3d3_+d4!第三层目标函数
s.t.
2x1+2x2<=12
200x1+300x2+d1_-d1=1500
2x1-x2+d2_-d2=0
4x1+d3_-d3=16
5x2+d4_-d4=15
d1_=0 !第一层目标优化结果
d2_=0 !第二层
d2=0 !第二层
最中结果为
Global optimal solution found.
Objective value: 29.00000
Infeasibilities: 0.000000
Total solver iterations: 0
Variable Value Reduced Cost
D3 0.000000 6.000000
D3_ 8.000000 0.000000
D4 5.000000 0.000000
X1 2.000000 0.000000
X2 4.000000 0.000000
D1_ 0.000000 0.000000
D1 100.0000 0.000000
D2_ 0.000000 0.000000
D2 0.000000 0.000000
D4_ 0.000000 1.000000
可以解得 x1=2 ;x2=4为最优解
对于第一层目标d1_为0,为最小值满足第一层目标
对于第二层目标d2_+d2为0,也为最小值,满足第二次目标
对于第三次目标
3d3+3d3_+d4 结果为29 ,已经为最大化程度满足。
lingo还是简单,用起来很爽,这里给一个lingo操作教程,供大家一起学习(我也没看完,收藏了就算看了-_-)
https://zhuanlan.zhihu.com/p/231026008
虽然用lingo实现了,但是和我想的还不太一样,如果能用python实现的话,还可以设计一个计算UI供学生实现,还是强调一个目的:“能算”,让学生能在一节课时间内掌握最初级的运筹能力。
加油!!!