关键词:Python、调包、线性规划、指派问题、运输问题、pulp、混合整数线性规划(MILP)
注:此文章是线性规划的调包实现,具体步骤原理请搜索具体解法。
本文章的各个问题可能会采用多种调用方法,为什么?因为这些包各有特点,有些语法特别像matlab,只要稍稍改变即可达成代码交换;而有些包利用了python本身的特性,在灵活度与代码的可读性上更高。我认为这些包各有优劣,各位各持所需吧。
看了本文章能做到什么?你可以在本文章内学到线性规划的几个问题的求解方式,并学会如何用pulp包解决线性规划问题。无论是整数规划(Integer Program)、01规划(Binary Program)还是混合整数线性规划(MILP),你都可以得到很好的解题方法。
一、线性规划
该问题引用自《数学建模算法与应用-司守奎》第一章线性规划 3.线性规划
包的具体使用可参考scipy官网
求解最普通的线性规划问题:
scipy调包代码
import numpy as np
z = np.array([2, 3, 1])
a = np.array([[1, 4, 2], [3, 2, 0]])
b = np.array([8, 6])
x1_bound = x2_bound = x3_bound =(0, None)
from scipy import optimize
res = optimize.linprog(z, A_ub=-a, b_ub=-b,bounds=(x1_bound, x2_bound, x3_bound))
print(res)
#output:
# fun: 7.0
# message: 'Optimization terminated successfully.'
# nit: 2
# slack: array([0., 0.])
# status: 0
# success: True
# x: array([0.8, 1.8, 0. ])
注意,此函数和matlab的linprog有很多相似之处。
首先默认就是求解最小值,如果想要求最大值,需要对目标函数的各参数取反(既对z取反),并在得出的结果(func)前取反。
并且所有约束条件都为≤,因此例子中传入参数是前面都加了负号。
bound为边界的二元元组,None时为无边界。
如果存在类似
这种情况,可以:
A_eq = [[1,2,4]]
b_eq = [101]
并在linprog中传入。
得出的结果为scipy.optimize.optimize.OptimizeResult(优化结果)类型,是类似字典的结构,例如想要优化结果代入目标函数的值,可以res.fun或res['fun']这样取值。
pulp调包代码
import pulp
#目标函数的系数
z = [2, 3, 1]
#约束
a = [[1, 4, 2], [3, 2, 0]]
b = [8, 6]
#确定最大化最小化问题,最大化只要把Min改成Max即可
m = pulp.LpProblem(sense=pulp.LpMinimize)
#定义三个变量放到列表中
x = [pulp.LpVariable(f'x{i}', lowBound=0) for i in [1,2,3]]
#定义目标函数,lpDot可以将两个列表的对应位相乘再加和
#相当于z[0]*x[0]+z[1]*x[0]+z[2]*x[2]
m += p