运筹学,是现代管理学的一门重要专业基础课。它是20世纪30年代初发展起来的一门新兴学科,其主要目的是在决策时为管理人员提供科学依据,是实现有效管理、正确决策和现代化管理的重要方法之一。该学科应用于数学和形式科学的跨领域研究,利用统计学、数学模型和算法等方法,去寻找复杂问题中的最佳或近似最佳的解答。
运筹学经常用于解决现实生活中的复杂问题,特别是改善或优化现有系统的效率。 研究运筹学的基础知识包括实分析、矩阵论、随机过程、离散数学和算法基础等。而在应用方面,多与仓储、物流、算法等领域相关。因此运筹学与应用数学、工业工程、计算机科学、经济管理等专业相关。
运筹学是数学模型的真子集
主要分支有:数学规划、图论、博弈论、决策论、排队论等
应用运筹学处理问题时分为5个阶段:
①规定目标和明确问题:包括把整个问题分解成若干子问题,确定问题的尺度、有效性度量、可控变量和不可控变量,以及用来表示变量界限和变量间关系的常数和参数。
②收集数据和建立模型:包括定义关系、经验关系和规范关系。
③求解模型和优化方案:包括确定求解模型的数学方法,程序设计和调试,仿真运行和方案选优。
④检验模型和评价解答:包括检验模型的一致性、灵敏度、似然性和工作能力,并用试验数据来评价模型的解。一致性是指主要参数变动时(尤其是变到极值时)模型得出的结果是否合理;灵敏度是指输入发生微小变化时输出变化的相对大小是否合适;似然性是指对于真实数据的案例,模型是否适应;工作能力则是指模型是否容易解出,即在规定时间内算出所需的结果。
⑤方案实施和不断优化:包括应用所得的解解决实际问题,并在方案实施过程中发现新的问题和不断进行优化。上述5个阶段往往需要交叉进行,不断反复。
线性规划、非线性规划、整数规划、目标规划、动态规划等。
分类 | 应用 |
---|---|
线性规划 | 主要解决生产计划问题,合理下料问题,最优投资问题 |
非线性规划 | 如证券投资组合优化:如何合理投资使风险最小 |
动态规划 | 分阶段决策问题,比较经典的是最短路径问题 |
整数规划 | 在线性规划的基础上,变量加上整数约束,比较经典的是0-1背包问题 |
目标规划 | 多目标并存;应用范围较广,企业管理中经常会用到 |
优化条件:问题所要达到的目标能用函数描述,且能用极值(max或者min)来表示
限定条件:达到目标受到一定的限制,且这些限制能够用决策变量的等式或者不等式表示
选择条件:有多种可选择的方案供决策者选择,以便找出最优方案
根据影响所要达到目的的因素找到决策变量;
由决策变量和所在达到目的之间的函数关系确定目标函数,明确是max还是min;
由决策变量所受的限制条件确定决策变量所要满足的约束条件。
当我们得到的数学模型的目标函数为线性函数,约束条件为线性等式或不等式时称此数学模型为线性规划模型。
线性规划问题可以手解的方法有“图解法“和”单纯形法”。“图解法”顾名思义,就是画图求出最优解;”单纯形法”是一个特别有趣的方法,具体操作请参考后文的参考资料(3)~
step1:将模型表达式转化为标准模式
m i n c T x s . t . { A u b x ≤ b u b A e q ∗ x = b e q l ≤ x ≤ u min \quad c^Tx\\ s.t. \quad \begin{cases} A_{ub}x \leq b_{ub} \\ A_{eq}*x = b_{eq} \\ l \leq x \leq u \end{cases} mincTxs.t.⎩⎪⎨⎪⎧Aubx≤bubAeq∗x=beql≤x≤u
其中x是决策变量的向量; c, b_ub, b_eq, l,和 u是向量;和 Aub 和 Aeq 是矩阵
step2:Python求解
from scipy import optimize
import numpy as np
#求解函数
res = optimize.linprog(c,Aub,bub,Aeq,beq,l,u,X0,OPTIONS)
#目标函数最小值
print(res.fun)
#最优解
print(res.x)
需要注意的问题:
1、在线性规划问题中,标准形式中目标函数表达式为max;在python函数中,标准形式中目标函数表达式为min!!!在写python表达式时,请一定要格外注意c值的正负问题~~!!!
2、标准形式中,弹性约束的符号是小于等于,请一定要注意Aub矩阵每一行的正负问题
扩展小知识1:
MATLAB求解代码如下:
[x,fval]=linprog(c,A,b,Aeq,beq,l,u,X0,OPTIONS)
生产安排模型:某工厂要安排生产Ⅰ、Ⅱ两种产品,已知生产单位产品所需的设备台时及A、B两种原材料的消耗,如表所示,表中右边一列是每日设备能力及原材料供应的限量,该工厂生产一单位产品Ⅰ可获利2元,生产一单位产品Ⅱ可获利3元,问应如何安排生产,使其获得最多?
Ⅰ | Ⅱ | ||
---|---|---|---|
设备 | 1 | 2 | 8(台时) |
原材料A | 4 | 0 | 16(kg) |
原材料B | 0 | 4 | 12(kg) |
利润(元/kg) | 2 | 3 |
假定:工厂分别生产产品Ⅰ和Ⅱx_1、x_2
模型可记为:
m a x z = 2 x 1 + 3 x 2 s . t . { x 1 + 2 x 2 ≤ 8 4 x 1 ≤ 16 4 x 2 ≤ 12 x 1 , x 2 ≥ 0 max \quad z=2x_1+3x_2\\ s.t. \quad \begin{cases} x_1+2x_2 \leq 8 \\ 4x_1 \leq 16 \\ 4x_2 \leq 12 \\ x_1,x_2 \geq 0 \end{cases} maxz=2x1+3x2s.t.⎩⎪⎪⎪⎨⎪⎪⎪⎧x1+2x2≤84x1≤164x2≤12x1,x2≥0
python代码如下:
#导入包
from scipy import optimize
import numpy as np
c = np.array([2,3])
Aub = np.array([[1,2],[4,0],[0,4]])
bub = np.array([8,16,12])
#求解
res = optimize.linprog(-c,Aub,bub)
print(res)
结果如下:
#等式约束的残差
con: array([], dtype=float64)
#目标函数的最佳值
fun: -13.999999982532964
message: 'Optimization terminated successfully.'
#在所有阶段中执行的迭代总数
nit: 4
#不等式约束的松弛值
slack: array([1.02599227e-08, 1.66172107e-08, 4.00000001e+00])
#表示算法退出状态的整数(0:优化成功终止)
status: 0
#当算法成功找到最佳解决方案时为True
success: True
#在满足约束的情况下将目标函数最小化的决策变量的值
x: array([4., 2.])
扩展知识2:
在线性规划中有一个很重要的知识点就是“对偶”的概念。
比如说,下面的例子换一种问法:若厂长决定不生产Ⅰ和Ⅱ两种产品,决定向外销售两种原料,只收加工费,那么两种原料如何定价才是最佳决策?
由于“对偶”问题时一个纯数学问题,其意义在于讨论“影子价格”的问题,但其中的模型变化、性质等十分繁复,只要写出来标准形式的数学模型,在python实现方面没有什么变化,所以这里就过多赘述了,如果感兴趣的小伙伴,可以看一下后文的参考资料(5)~
注:影子价格:是在取得原问题最优解后,在其它条件不变的情况下(最重要的是最优基不变),某一资源限制被增加了一个单位,其它资源的限制不变,给目标函数增加的收益。
扩展知识3:
在线性规划的领域中,还有一类经典问题——“运输问题”,包括产销平衡和产销不平衡,在数学角度解决“运输问题”有一个方法叫做“表上作业法”,也是一个很有意思的纸上画画画的过程,虽然形式上有所变化,但其根本依然是“单纯型法”。请参照后文的参考资料(6)
扩展小知识4:
目标规划问题也可以通过增加正负偏差变量,变为线性规划问题进行python编程解决哦~
scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)
重要参数解析:
参数 | 解释 |
---|---|
fun | 最小化的目标函数 |
x0 | 变量初始值数组,ndarray(n) |
method | 默认SLSQP(最小二乘) |
constraints | 约束条件 |
求下式最小值:
2 + x 1 1 + x 2 − 3 x 1 + 4 x 3 ( 0.1 ≤ x 1 , x 2 , x 3 ≤ 0.9 ) \frac{2+x_1}{1+x_2}-3x_1+4x_3 \quad (0.1 \leq x_1,x_2,x_3 \leq 0.9) 1+x22+x1−3x1+4x3(0.1≤x1,x2,x3≤0.9)
python代码如下:
from scipy.optimize import minimize
import numpy as np
def fun(args):
a,b,c,d=args
v=lambda x: (a+x[0])/(b+x[1]) -c*x[0]+d*x[2]
return v
def con(args):
# 约束条件 分为eq 和ineq
#eq表示 函数结果等于0 ; ineq 表示 表达式大于等于0
x1min, x1max, x2min, x2max,x3min,x3max = args
cons = ({'type': 'ineq', 'fun': lambda x: x[0] - x1min},\
{'type': 'ineq', 'fun': lambda x: -x[0] + x1max},\
{'type': 'ineq', 'fun': lambda x: x[1] - x2min},\
{'type': 'ineq', 'fun': lambda x: -x[1] + x2max},\
{'type': 'ineq', 'fun': lambda x: x[2] - x3min},\
{'type': 'ineq', 'fun': lambda x: -x[2] + x3max})
return cons
if __name__ == "__main__":
#定义常量值
args = (2,1,3,4) #a,b,c,d
#设置参数范围/约束条件
args1 = (0.1,0.9,0.1, 0.9,0.1,0.9)
cons = con(args1)
#设置初始猜测值
x0 = np.asarray((0.5,0.5,0.5))
res = minimize(fun(args), x0,method='SLSQP',constraints=cons)
print(res)
结果如下:
#目标函数的最佳值
fun: -0.773684210526435
#函数的雅可比矩阵
jac: array([-2.47368421, -0.80332409, 4. ])
message: 'Optimization terminated successfully'
nfev: 8
nit: 2
njev: 2
#表示算法退出状态的整数(0:优化成功终止)
status: 0
success: True
#在满足约束的情况下将目标函数最小化的决策变量的值
x: array([0.9, 0.9, 0.1])
①原线性规划最优解全是整数,则整数规划最优解与线性规划最优解一致
②整数规划无可行解
分枝定界法——可求纯或混合整数线性规划问题
割平面法——可求纯或混合整数线性规划
隐枚举法——求解“0-1”整数规划:
①过滤隐枚举法;
②分枝隐枚举法。
有一份中文说明书,需译成英、日、德、俄四种文字,分别记作A、B、C、D。现有甲、乙、丙、丁四人,他们将中文说明书译成不同语种的说明书所需时间如下表所示,问如何分派任务可是总时间最少?
A | B | C | D | |
---|---|---|---|---|
甲 | 6 | 7 | 11 | 2 |
乙 | 4 | 5 | 9 | 8 |
丙 | 3 | 1 | 10 | 4 |
丁 | 5 | 9 | 8 | 2 |
系数矩阵:
匈牙利变换后的最优解矩阵:
匈牙利法的python函数
scipy.optimize.linear_sum_assignment(cost_matrix, maximize=False)
Python代码:
from scipy.optimize import linear_sum_assignment
cost = np.array([[6,7,11,2],[4,5,9,8],[3,1,10,4],[5,9,8,2]])
row_ind,col_ind=linear_sum_assignment(cost)
print(row_ind)#开销矩阵对应的行索引
print(col_ind)#对应行索引的最优指派的列索引
print(cost[row_ind,col_ind])#提取每个行索引的最优指派列索引所在的元素,形成数组
print(cost[row_ind,col_ind].sum())#数组求和
结果如下:
[0 1 2 3]
[3 0 1 2]
[2 4 1 8]
#最后的最优解,即总时间为15
15
(1) 运筹学(管理类专业基础课) - 百度百科
(2) 运筹学-MBA智库
(3) 单纯型法手算详解
(4) scipy.optimize.linprog(官方文档)
(5) 线性规划的对偶问题 - 知乎
(6) 表上作业法
(7) scipy.optimize.minimize (官方文档)
(8) scipy.optimize.linear_sum_assignment(官方文档)