文章目录

  • 1 PuLP介绍
    • 1.1 理论、流程介绍
    • 1.2 主函数介绍
      • 1.2.1 LpProblem类
      • 1.2.2 LpVariable类
      • 1.2.3 lpSum(vector)
    • 1.3 一些函数写法优化
      • 1.3.1 赋值
      • 1.3.2 PuLP里面不可使用的
  • 案例一:优化投放广告渠道的资源
  • 案例二:如何分配水库供水量,公司才能获利最多
  • 案例三: 求解最普通的线性规划问题
  • 案例四:运输问题
  • 案例五:指派问题

1 PuLP介绍

参考:用Python的pulp解决线性规划问题

1.1 理论、流程介绍

线性规划是研究线性约束条件下线性目标函数的极值问题的数学理论和方法。Python中有许多第三方的工具可以解决这类问题,这里介绍常用的pulp工具包。pulp能够解包括整数规划在内的绝大多数线性规划问题,并且提供了多种solver,每种solver针对不同类型的线性规划问题有更好的效果。
关于pulp工具包的详细介绍,请参见pulp官网。

pip install pulp

我们解决线性规划问题一般是通过以下三个步骤。

  • 1.列出约束条件及目标函数
  • 2.画出约束条件所表示的可行域
  • 3.在可行域内求目标函数的最优解及最优值

1.2 主函数介绍

1.2.1 LpProblem类

LpProblem(name='NoName', sense=LpMinimize)
构造函数,用来构造一个LP问题实例,其中name指定问题名(输出信息用),
sense值是LpMinimizeLpMaximize中的一个,用来指定目标函数是求极大值还是极小值。

solve(solver=None, **kwargs)
在对LpProblem添加完约束条件后,调用该函数进行求解,如果不是求解特定的整数规划问题,solver一般使用默认即可。

1.2.2 LpVariable类

LpVariable(name, lowBound=None, upBound=None, cat='Continuous', e=None)
构造函数,用来构造LP问题中的变量,name指定变量名,lowBound和upBound是下界和上界,
默认分别是负无穷到正无穷,cat用来指定变量是离散(Integer,Binary)还是连续(Continuous)。
取值包括:

  • LpInteger - 整数型
  • LpContinuous - 连续性

dicts(name, indexs, lowBound=None, upBound=None, cat='Continuous', indexStart=[])
用来构造变量字典,可以让我们不用一个个地创建Lp变量实例。name指定所有变量的前缀,
index是列表,其中的元素会被用来构成变量名,后面三个参数和LbVariable中的一样。

1.2.3 lpSum(vector)

计算一个序列的值,使用lpSum求解比普通的sum函数要快得多。

1.3 一些函数写法优化

1.3.1 赋值

变量定义,注意最后的LpInteger,当设置该参数时,则该决策变量只能取整数
如果决策变量可以取小数,那就设置为LpContinuous

x1 = LpVariable('日间电视',0,14,LpInteger)
x2 = LpVariable('夜间电视',0,8,LpInteger)
x3 = LpVariable('网络媒体',0,40,LpInteger)
x4 = LpVariable('平面媒体',0,5,LpInteger)
x5 = LpVariable('户外广告',0,50,LpInteger)

变成了:

Ingredients = ['日间电视','夜间电视','网络媒体','平面媒体','户外广告']
ingredient_vars = LpVariable.dicts("Ingr",Ingredients,0)

1.3.2 PuLP里面不可使用的

不可以使用:
x1/x2
1/x1
x2/3


案例一:优化投放广告渠道的资源

来看一个案例:如何用Python解决最优化问题?

现有5个广告投放渠道,分别是日间电视、夜间电视、网络媒体、平面媒体、户外广告,每个渠道的效果、费用及限制如下表所示:


注:案例来自《活用数据:驱动业务的数据分析实战》,作者陈哲

比如日间电视这个渠道,每做一次投放需要费用1000元,可以触达2000个用户(曝光量),带来咨询量600个(也可以看做app下载量等目标产出),该广告渠道最多投放14次。

除了表格中的限制条件外,还要求:

电视广告至少投放20次(包括日间和夜间);
触达用户数(曝光量)不少于10万;
电视广告投入费用不超过3万元;
现在公司总共给到4万的营销费用,要求咨询量能最大化。

这是一个线性规划问题,即在有限的资源(约束条件)下如何使效用(线性目标函数)最大化。
把5个广告渠道各自能使用的次数作为决策变量,分别用

来表示

那么,现在要优化的目标函数是

约束条件:

电视广告投放至少20次,

用户曝光量至少10万,

电视广告费用不超过3万,

总广告费用不超过4万,

投放次数为正整数,且


使用PuLP的代码为:

from pulp import *prob = LpProblem('营销优化问题',LpMaximize)# 变量定义,注意最后的LpInteger,当设置该参数时,则该决策变量只能取整数
# 如果决策变量可以取小数,那就设置为LpContinuous
x1 = LpVariable('日间电视',0,14,LpInteger)
x2 = LpVariable('夜间电视',0,8,LpInteger)
x3 = LpVariable('网络媒体',0,40,LpInteger)
x4 = LpVariable('平面媒体',0,5,LpInteger)
x5 = LpVariable('户外广告',0,50,LpInteger)# 需要优化的表达式
prob += 600*x1+800*x2+500*x3+400*x4+300*x5# 约束条件
prob += 1000*x1 + 2000*x2 <= 30000, '电视广告费用不超过3万'
prob += x1+x2 >= 20, '电视广告至少20次'
prob += 1000*x1+2000*x2+400*x3+1000*x4+100*x5 <= 40000, '广告总费用不超过4万'
prob += 2000*x1+4000*x2+3000*x3+5000*x4+600*x5 >= 100000,'曝光人数不少于10万'#lp文件保存该优化问题的信息,可以用文本编辑器打开
prob.writeLP("营销优化问题.lp")# 执行计算
prob.solve()# 如果成功得到了最优值,则会输出 Optimal
print(LpStatus[prob.status])# 得到最优值时,各决策变量的取值,如果没有找到最优值,则输出None
for v in prob.variables():print(v.name, "=", v.varValue)# 输出最优值,如果没有找到最优值,则输出None
print("最大咨询量为", value(prob.objective))

输出结果:

可以看到最优值为39200,对应的决策变量的取值均为整数。

PuLP的代码量看着虽然多,但是相对于scipy.optimize.linprog函数,PuLP的代码非常灵活,而且很直观,对参数取值是整数或者小数还有细分。


案例二:如何分配水库供水量,公司才能获利最多

python 之pulp 线性规划介绍及举例

供水公司有三个水库分别为A,B,C向四个小区甲乙丙丁供水,A和B向所有小区供水,C仅向甲乙丙供水,水库最大供水量(千吨)

小区用水情况为

水库供水收入900元/千吨,支出费用为:其他费用450/千吨,引水管理费:

问 如何分配水库供水量,公司才能获利最多。
目标函数为:

z = 160.0*x11 + 130.0*x12 + 220.0*x13 + 170.0*x14 + 140.0*x21 + 130.0*x22 + 190.0*x23 + 150.0*x24 + 190.0*x31 + 200.0*x32 + 230.0*x33

求的值,使Z最小。

# coding=utf-8from pulp import *def get_re():passdef getresult(c, con):# 设置对象prob = LpProblem('myPro', LpMinimize)
# 设置三个变量,并设置变量最小取值x11 = LpVariable("x11", lowBound=0)x12 = LpVariable("x12", lowBound=0)x13 = LpVariable("x13", lowBound=0)x14 = LpVariable("x14", lowBound=0)x21 = LpVariable("x21", lowBound=0)x22 = LpVariable("x22", lowBound=0)x23 = LpVariable("x23", lowBound=0)x24 = LpVariable("x24", lowBound=0)x31 = LpVariable("x31", lowBound=0)x32 = LpVariable("x32", lowBound=0)x33 = LpVariable("x33", lowBound=0)X = [x11, x12, x13, x14, x21, x22, x23, x24, x31, x32, x33]#c = [160, 130, 220, 170, 140, 130, 190, 150, 190, 200, 230]# 目标函数z = 0for i in range(len(X)):z += X[i]*c[i]#print(z)prob += z# 载入约束变量prob += x11+x12+x13+x14 == con[0]# 约束条件1prob += x21+x22+x23+x24 == con[1]prob += x31+x32+x33 == con[2]prob += x11+x21+x31 <= con[3]prob += x11+x21+x31 >= con[4]prob += x12 + x22 + x32 <= con[5]prob += x12 + x22 + x32 >= con[6]prob += x13 + x23 + x33 <= con[7]prob += x13 + x23 + x33 >= con[8]prob += x14 + x24 <= con[9]prob += x14 + x24 >= con[10]# 求解status = prob.solve()print(status)print(LpStatus[status])print(value(prob.objective))  # 计算结果# 显示结果
#     for i in prob.variables():
#         print(i.name + "=" + str(i.varValue))for i in prob.variables():print(i.varValue)if __name__ == '__main__':c = [160, 130, 220, 170, 140, 130, 190, 150, 190, 200, 230]con = [50, 60, 50, 80, 30, 140, 70, 30,10, 50, 10]getresult(mubiao, yueshu)

输出结果:

Optimal24400.00.050.00.00.00.050.00.010.040.00.010.0

案例三: 求解最普通的线性规划问题

【数学建模】线性规划各种问题的Python调包方法
求解最普通的线性规划问题:

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 += pulp.lpDot(z, x)#设置约束条件
for i in range(len(a)):m += (pulp.lpDot(a[i], x) >= b[i])
#求解
m.solve()
#输出结果
print(f'优化结果:{pulp.value(m.objective)}')
print(f'参数取值:{[pulp.value(var) for var in x]}')#output:
#优化结果:7.0
#参数取值:[2.0, 0.0, 3.0]

每一步的说明已经注释在代码中,可以看到输出结果,两者的变量取值并不一致,但代入目标函数的结果都是一样的。
  同样的,如果存在类似x_1+2x_2+4x_3=101这种情况,可以:

A_eq = [1,2,4]
b_eq = 101
m += (pulp.lpDot(A_eq, x) == b_eq)

案例四:运输问题

【数学建模】线性规划各种问题的Python调包方法

import pulp
import numpy as np
from pprint import pprintdef transportation_problem(costs, x_max, y_max):row = len(costs)col = len(costs[0])prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMaximize)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[i][j] for i in range(row)]) <= y_max[j])prob.solve()return {'objective':pulp.value(prob.objective), 'var': [[pulp.value(var[i][j]) for j in range(col)] for i in range(row)]}

然后构造参数传递进去:

if __name__ == '__main__':costs = np.array([[500, 550, 630, 1000, 800, 700],[800, 700, 600, 950, 900, 930],[1000, 960, 840, 650, 600, 700],[1200, 1040, 980, 860, 880, 780]])max_plant = [76, 88, 96, 40]max_cultivation = [42, 56, 44, 39, 60, 59]res = transportation_problem(costs, max_plant, max_cultivation)print(f'最大值为{res["objective"]}')print('各变量的取值为:')pprint(res['var'])#output:
#最大值为284230.0
#各变量的取值为:
#[[0.0, 0.0, 6.0, 39.0, 31.0, 0.0],
# [0.0, 0.0, 0.0, 0.0, 29.0, 59.0],
# [2.0, 56.0, 38.0, 0.0, 0.0, 0.0],
# [40.0, 0.0, 0.0, 0.0, 0.0, 0.0]]

案例五:指派问题

【数学建模】线性规划各种问题的Python调包方法

先定义通用解决方法,其中的flatten是递归展开列表用的。

def assignment_problem(efficiency_matrix):row = len(efficiency_matrix)col = len(efficiency_matrix[0])flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x]m = pulp.LpProblem('assignment', sense=pulp.LpMinimize)var_x = [[pulp.LpVariable(f'x{i}{j}', cat=pulp.LpBinary) for j in range(col)] for i in range(row)]m += pulp.lpDot(efficiency_matrix.flatten(), flatten(var_x))for i in range(row):m += (pulp.lpDot(var_x[i], [1]*col) == 1)for j in range(col):m += (pulp.lpDot([var_x[i][j] for i in range(row)], [1]*row) == 1)m.solve()print(m)return {'objective':pulp.value(m.objective), 'var': [[pulp.value(var_x[i][j]) for j in range(col)] for i in range(row)]}

输出结果:

efficiency_matrix = np.array([[12, 7, 9, 7, 9],[8, 9, 6, 6, 6],[7, 17, 12, 14, 9],[15, 14, 6, 6, 10],[4, 10, 7, 10, 9]
])res = assignment_problem(efficiency_matrix)
print(f'最小值{res["objective"]}')
print(res['var'])#output
#最小值32.0
#[[0.0, 1.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 1.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0]]

最优解问题——PuLP解决线性规划问题(一)相关推荐

  1. 规划求解 python_使用Python/PuLp解决线性规划问题

    Python中有许多第三方的工具可以解决这类问题,本教程介绍pulp工具包的使用. 一 · 教程讲解视频 二 · 常用的线性规划求解软件 1.Excel 2.Lingo 3.Matlab 三 · Py ...

  2. python的pulp包_使用Python/PuLp解决线性规划问题

    Python中有许多第三方的工具可以解决这类问题,本教程介绍pulp工具包的使用. 一 · 教程讲解视频 二 · 常用的线性规划求解软件 1.Excel 2.Lingo 3.Matlab 三 · Py ...

  3. Python使用PuLP第三方库解决线性规划问题

    假设我们考虑投资两种证券X和Y.若投资X证券的数量为xxx,投资Y证券的数量为yyy, 试求3x+2y3x+2y3x+2y的最大值.限制条件如下: 投资2倍的X证券数量与投资Y证券数量之和不超过100 ...

  4. pulp和scipy库解决线性规划

    目录 1.pulp库解决简单线性规划问题 2.pulp库解决大型线性规划问题 3.scipy库解决线性规划 1.pulp库解决简单线性规划问题 ''' max fx = 2*x1 + 3*x2 - 5 ...

  5. python引入包pulp_用python的pulp库解决线性规划问题

    本文会介绍怎么用python解决线性规划问题,为什么要用python而不是matlab和lingo呢?因为matlab的函数写法不太符合正常的思维方式,编起来很复杂.而lingo虽然编写容易,但报错不 ...

  6. python Pulp求解线性规划问题

      线性规划是研究线性约束条件下线性目标函数的极值问题的数学理论和方法.Python中有许多第三方的工具可以解决这类问题,这里介绍常用的pulp工具包.pulp能够解包括整数规划在内的绝大多数线性规划 ...

  7. 三、lingo学习笔记——解决线性规划

    lingo软件主要用于解决线性规划问题. - 一个经典的线性规划问题的lingo实现如下: max=2*x1+3*x2; x1+2*x2<=8; 4*x1<=16; 4*x2<=12 ...

  8. MATLAB解决线性规划问题,学会使用linprog函数,在一个实例中演示linprog函数各参数的用法

    最近接触到了一个线性规划的题目,尝试用MATLAB解决,动手前想了很多思路,上网搜索了一下发现MATLAB中有专门的linprog函数专门解决线性规划问题,了解学习后果然十分方便.事实上,绝大部分的线 ...

  9. 利用Matlab解决线性规划问题并绘制特定形状的空间曲面(约束区域的绘图)

    今天女朋友给我发了一个问题 让我帮忙把这个空间平面y给画出来 我寻思着正好前段时间学了一些matlab的绘制曲面的方法,说不定刚好可以用上 那么就开始分析吧! 这应该就是一个高中常见的二元优化问题,但 ...

最新文章

  1. 消息队列-----生成者 Spring整合rabbitmq
  2. Python 3下Matplotlib画图中文显示乱码的解决方法
  3. poj-1031-fence(不是我写的,我只是想看着方便)
  4. 2017-2018-1 20155234《信息安全系统设计基础》第五周学习总结
  5. SAP UI5 return sap.ui.view的实现
  6. SQL Server2008附加数据库失败
  7. CoderForces999D-Equalize the Remainders
  8. 电脑如何进入bios模式_电脑如何进入bios,你还不收藏?
  9. 《YOLO系列原理实战笔记》高清.pdf
  10. Leetcode 刷题笔记(二十六) ——动态规划篇之经典问题:打家劫舍
  11. MapReduce:详解Shuffle过程
  12. Javascript:面向对象举例——矩形类及其实例化
  13. 将PDG文件转化为PDF文件
  14. 网络防火墙开发二三事
  15. en结尾的单词_以en结尾的形容词
  16. (基础)Promise中then()方法使用,多次调用、链式调用
  17. H-A + B用于投入产出实践(VIII)
  18. 怎样将文件压缩并传到服务器,客户端上传压缩文件(zip)的思路和实现
  19. 小米 android 7.0彩蛋,手把手教你小米怎么刷入安卓7.0!
  20. 打不开我的电脑 显示服务器,我的电脑服务器打不开。怎么办?

热门文章

  1. python chm模块_python3.7.0官方参考文档 最新api文档 chm
  2. python 实现实时语音对讲
  3. ssh协议(git和github gitee 之间的传输协议)
  4. linux平台下的6818开发板(ARM)显示屏的字体显示
  5. cad怎么将图层后置_Auto CAD2014图层后置快捷键是什么啊?
  6. vue项目报错:warning Disallow self-closing on HTML void elements (<img/>)
  7. linux达人养成计划i,Linux达人养成计划 I
  8. 关于NOI Linux的IDE及代码调试技巧(OIER必看)
  9. 【Android系统】虚拟按键 平板设备中重叠的问题
  10. 新生儿的一类(免费)疫苗(截止2019年)