在这里插入代码片# 运筹学
- 线性规划
线性规划
概念:约束条件及目标函数都是决策变量的线性函数的规划问题。
缺陷: 线性规划只能解决一组线性约束条件下,一个目标的最大值或最小值问题。
在实际决策中,衡量方案优劣要考虑多个目标,这些目标中,有主要的,也有次要的;有最大值的,也有最小值的;有定量的,也有定性的;有相互补充的,也有相互对立的。对于这些问题,线性规划则无能为力。——线性目标规划
(化简立)即得标准型
eg.求解
Python 代码
法一:scipy.optimize.linprog
linprog(c, A_ub=None, b_ub=None, A_eq=None, b_eq=None, bounds=None, method='simplex', callback=None, options=None)
参数解释:
c是价值向量;
A_ub和b_ub对应线性不等式约束;
A_eq和b_eq对应线性等式约束;
bounds对应公式中的lb和ub,决策向量的下界和上界;
method是求解器的类型,如单纯形法;
其他的参数暂时不用。
注意:用此方法求解,都需要把方程组转化成标准形式!
from scipy.optimize import linprog # 导包
C = [-1,4] # 价值向量
A = [[-3,1],[1,2]] # 系数矩阵
b = [6,4] # 约束向量
# 给每个决策变量指定取值范围
X0_bounds = [None,None]
X1_bounds = [-3,None]
res = linprog(C,A,b,bounds=(X0_bounds,X1_bounds))
print(res) # 输出结果
'''
con: array([], dtype=float64)
fun: -22.0 # 最优值
message: 'Optimization terminated successfully.'
nit: 5
slack: array([3.90000000e+01, 1.77635684e-15])
status: 0
success: True
x: array([10., -3.]) # 最优解
'''
若是非标准形式,如求最大值:
再去求解!
Matlab代码
[x,fval]=linprog(c,A,b,Aeq,beq,LB,UB,X0,OPTIONS)
参数解释:
x :返回决策向量的取值
fval :返回目标函数的最优值
f :价值向量
A :线性不等式约束的系数向量(跟Python要输入成矩阵不同,Matlab输入向量)
b :线性不等式约束的约束向量
Aeq : 线性等式约束的系数向量(跟Python要输入成矩阵不同,Matlab输入向量)
beq :线性不等式约束的约束向量
LB:决策向量的下界向量
UB:决策变量的上界向量
f = [-1, 4];
A = [-3, 1; 1, 2];
b = [6, 4];
lb = [0, -3];
[x, y] = linprog(f, A,b,[],[],lb,[])
Lingo代码
min=-1*x1+4*x2;
-3*x1+1*x2<=6;
1*x1+2*x2<=4;
x2 >= -3;
@free(x2);
需要用到单纯形法
步骤与上相同,不用考虑像用笔算那样加入人工变量。
Python代码
z = [-2, -3, 5]
A = [[-2, 5, -1], [1, 3, 1]]
B = [-10, 12]
Aeq = [[1, 1, 1]]
beq = [7]
res = linprog(z, A, B, Aeq, beq, bounds=(x1_bounds,x2_bounds,x3_bounds))
print(res)
'''
con: array([0.])
fun: -14.571428571428571
message: 'Optimization terminated successfully.'
nit: 3
slack: array([0. , 3.85714286])
status: 0
success: True
x: array([6.42857143, 0.57142857, 0. ])
'''
Matlab代码
f=[-2; -3; 5];
a=[-2,5,-1;1,3,1]; b=[-10;12];
aeq=[1,1,1];
beq=7;
[x,y]=linprog(f,a,b,aeq,beq,zeros(3,1));
x, y=-y
Lingo代码
model:
sets:
row/1..2/:b;
col/1..3/:c,x;
links(row,col):a;
endsets
data:
c=2 3 -5;
a=-2 5 -1 1 3 1;
b=-10 12;
enddata
max=@sum(col:c*x);
@for(row(i):@sum(col(j):a(i,j)*x(j))<b(i));
@sum(col:x)=7;
end
运输问题
产销平衡
Python代码
import pulp
import numpy as np
from pprint import pprint
def transportation_problem(costs, x_max, y_max):
row = len(costs)
col = len(costs[0])
prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMinimize)
var = [[pulp.LpVariable(f'x{i}{j}', lowBound=0, cat=pulp.LpInteger) for j in range(col)] for i in range(row)]
flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x]
prob += pulp.lpDot(flatten(var), costs.flatten())
for i in range(row):
prob += (pulp.lpSum(var[i]) >= x_max[i])
for j in range(col):
prob += (pulp.lpSum([var