首页 > 其他分享 >线性规划——Pyhton线性规划求解库PULP的使用

线性规划——Pyhton线性规划求解库PULP的使用

时间:2023-11-27 16:47:37浏览次数:40  
标签:prob pulp 线性规划 Ingredients PULP Pyhton x2 x1 PuLP

PuLP是一个用于线性规划(LP)、整数线性规划(ILP)和混合整数线性规划(MILP)问题的Python库。PuLP的全称是"Python for Mathematical Programming",它提供了一个简单而强大的工具,使得用户能够定义优化问题、构建数学模型并使用不同的求解器进行求解。PuLP的主要特点之一是其易用性。它允许用户通过简单的方式定义优化问题,而无需深入了解数学规划的细节。PuLP的语法设计旨在使用户能够直观地表达问题的约束和目标函数。这种简洁而清晰的语法使得PuLP成为解决线性规划问题的理想选择,特别是对于那些对数学规划领域不太熟悉的用户。在PuLP中,用户可以轻松地定义变量、约束和目标函数。通过简单的API调用,用户可以指定变量的上下界、约束条件的系数以及目标函数的系数。PuLP还提供了对问题特性的检查和显示,以帮助用户验证模型的正确性。PuLP的使用不仅限于线性规划问题,还可以处理整数线性规划和混合整数线性规划。

一、PuLP库的使用

PuLP Main Topics教程
PuLP是一个开源的第三方工具包,可以求解线性规划、整数规划、混合整数规划问题。下面先介绍一下Pulp一些基础的库函数,再以一些例题为例进行重复讲解。
PuLP库的安装和导入:

pip install pulp
import pulp
import numpy as np

PuLP创建求解问题:

prob = pulp.LpProblem("LPProbDemo", sense=pulp.LpMaximize)
#pulp.LpProblem 是定义问题的构造函数。
#LPProbDemo是用户定义的问题名(用于输出信息)。
#sense用来指定求最小值/最大值问题,可选参数值:LpMinimize、LpMaximize

PuLP定义变量

x1 = pulp.LpVariable('x1',lowBound=0, upBound=None, cat=pulp.LpInteger)
x2 = pulp.LpVariable('x2', lowBound=0, upBound=None, cat=pulp.LpBinary)
x1 = pulp.LpVariable('x1', lowBound=0, upBound=7, cat='Continuous')
#x1,x2是用户定义的变量名
#lowBound、upBound用来设定决策变量的下界、上界;可以不定义下界/上界,默认的下界/上界是负无穷/正无穷。
#cat用来设定变量类型,可选参数值:pulp.LpInteger为离散变量;pulp.LpBinary为0-1变量;pulp.LpInteger为整数变量。

PuLP定义目标函数:

prob += 3*x1 + 5*x2
prob += 2*x0-5*x1+4*x2

PuLP定义约束条件:

prob += 2*x1 + x2 <= 100
prob += x1 + x2 <= 80
prob += x1 <= 40
prob += x2 <= 60

PuLP求解和状态函数:

prob.solve()
pulp.LpStatus[prob.status]     #合理Status: Optimal
pulp.value(prob.objective)     #目标函数值

二、PuLP库的使用示例

2.1示例1

import pulp
MyProbLP = pulp.LpProblem("LPProbDemo1", sense=pulp.LpMaximize)
x1 = pulp.LpVariable('x1', lowBound=0, upBound=7, cat='Continuous') 
x2 = pulp.LpVariable('x2', lowBound=0, upBound=7, cat='Continuous')
x3 = pulp.LpVariable('x3', lowBound=0, upBound=7, cat='Continuous') 
MyProbLP += 2*x1 + 3*x2 - 5*x3  	# 设置目标函数
MyProbLP += (2*x1 - 5*x2 + x3 >= 10)  # 不等式约束
MyProbLP += (x1 + 3*x2 + x3 <= 12)  # 不等式约束
MyProbLP += (x1 + x2 + x3 == 7)  # 等式约束
MyProbLP.solve()

# 输出求解状态
print("Status:", pulp.LpStatus[MyProbLP.status]) 
# 输出每个变量的最优值
for v in MyProbLP.variables():
    print(v.name, "=", v.varValue)  
# 输出最优解的目标函数值 
print("F(x) = ", pulp.value(MyProbLP.objective))  
# 输出结果如下
Status: Optimal
x1 = 6.4285714
x2 = 0.57142857
x3 = 0.0
F(x) =  14.57142851

2.2示例2

import pulp
import numpy as np
# 定义问题
ProbLP3 = pulp.LpProblem("ProbLP3", sense=pulp.LpMaximize)
# 定义变量
x1 = pulp.LpVariable('x1', lowBound=0, upBound=8, cat='Continuous')
x2 = pulp.LpVariable('x2', lowBound=0, upBound=7.5, cat='Continuous')
# 定义目标函数
ProbLP3 += 11 * x1 + 9 * x2
# 添加约束
ProbLP3 += 6 * x1 + 5 * x2 <= 60
ProbLP3 += 10 * x1 + 20 * x2 <= 150
# 求解问题
ProbLP3.solve()
# 输出结果
print("Problem Name:", ProbLP3.name)
print("Status:", pulp.LpStatus[ProbLP3.status])
# 输出每个变量的最优值
for variable in ProbLP3.variables():
    print(f"{variable.name} = {variable.varValue}")
# 输出最优解的目标函数值
print("F3(x) =", pulp.value(ProbLP3.objective))

三、案例——猫粮问题

问题描述:Uncle Ben's希望以尽可能低的成本生产他们的猫粮产品,同时确保它们符合罐头上显示的营养分析要求。猫粮的配料有chicken, beef, mutton,rice, wheat,gel,它们的成本分别是$0.013, $0.008,$0.010,$0.002, $0.005, $0.001。为了满足营养标准,每100g成品必须至少有8gProtein,6gfat,但是不超过2g的fibre以及0.4g的salt。下面是营养成分表。

Stuff Protein Fat Fibre Salt
Chicken 0.100 0.080 0.001 0.002
Beef 0.200 0.100 0.005 0.005
Mutton 0.150 0.110 0.003 0.007
Rice 0.000 0.010 0.100 0.002
Wheat bran 0.040 0.010 0.150 0.008
Gel 0.000 0.000 0.000 0.000

3.1 建模表示

为使得更改其他测试的任何问题数据变得更容易,我们将以代数方式定义问题的方式开始:
确定决策变量
决策变量是我们在罐中包含的不同成分的百分比。由于罐子重100g,这些百分比也代表每种成分包含的克数。请注意,这些百分比必须介于0和100之间。

\[x_1=一罐猫粮中所用鸡肉的百分比 \quad x_2=一罐猫粮中所用牛肉的百分比\\ x_3=一罐猫粮中所用羊肉的百分比\quad x_4=一罐猫粮中所用米饭的百分比\\ x_5=一罐猫粮中所用麦麸的百分比\quad x_6=一罐猫粮中所用凝胶的百分比 \]

制定目标函数
对于Whiskas猫食品问题,目标是最小化每罐猫食品成分的总成本,即

\[\min \quad 0.013x_1+0.008x_2+0.010x_3+0.002x_4+0.005x_5+0.001x_6 \]

确定约束条件
Whiskas猫食品问题的约束条件是:
- 百分比总和必须占整个罐子(= 100%)。
- 满足规定的营养分析要求。
“整罐”的约束是:

\[x_1+x_2+x_3+x_4+x_5+x_6=100 \]

为了满足营养分析要求,我们需要每100g至少8g蛋白质,6g脂肪,但不超过2g纤维和0.4g盐。为了制定这些约束条件,我们利用以前的每种成分贡献表。这使我们能够制定有关来自成分的蛋白质,脂肪,纤维和盐总贡献的以下约束条件:

\[ \begin{aligned} 0.100x_1&+0.200x_2+0.150x_3+0.000x_4+0.040x_5+0.0x_6≥8.0\\ 0.080x_1&+0.100x_2+0.110x_3+0.010x_4+0.010x_5+0.0x_6≥6.0\\ 0.001x_1&+0.005x_2+0.003x_3+0.100x_4+0.150x_5+0.0x_6≤2.0\\ 0.002x_1&+0.005x_2+0.007x_3+0.002x_4+0.008x_5+0.0x_6≤0.4 \end{aligned} \]

3.2 python实现

import numpy as np
from pulp import *

#Creates a list of the Ingredients
Ingredients = ['CHICKEN', 'BEEF', 'MUTTON', 'RICE', 'WHEAT', 'GEL']
# A dictionary of the costs of each of the Ingredients is created
costs = {'CHICKEN': 0.013,
'BEEF': 0.008,
'MUTTON': 0.010,
'RICE': 0.002,
'WHEAT': 0.005,
'GEL': 0.001}
# A dictionary of the protein percent in each of the Ingredients is created
proteinPercent = {'CHICKEN': 0.100,
'BEEF': 0.200,
'MUTTON': 0.150,
'RICE': 0.000,
'WHEAT': 0.040,
'GEL': 0.000}
# A dictionary of the fat percent in each of the Ingredients is created
fatPercent = {'CHICKEN': 0.080,
'BEEF': 0.100,
'MUTTON': 0.110,
'RICE': 0.010,
'WHEAT': 0.010,
'GEL': 0.000}
# A dictionary of the fibre percent in each of the Ingredients is created
fibrePercent = {'CHICKEN': 0.001,
'BEEF': 0.005,
'MUTTON': 0.003,
'RICE': 0.100,
'WHEAT': 0.150,
'GEL': 0.000}
# A dictionary of the salt percent in each of the Ingredients is created
saltPercent = {'CHICKEN': 0.002,
'BEEF': 0.005,
'MUTTON': 0.007,
'RICE': 0.002,
'WHEAT': 0.008,
'GEL': 0.000}
# 创建问题实例,求最小极值
prob = LpProblem("The Whiskas Problem", LpMinimize)

# 构建Lp变量字典,键名是Ingredients,值(变量名)以Ingr开头,如Ingr_CHICKEN,下界是0
ingredient_vars = LpVariable.dicts("Ingr", Ingredients, 0)
# 添加目标方程
prob += lpSum([costs[i] * ingredient_vars[i] for i in Ingredients])
# 添加约束条件
prob += lpSum([ingredient_vars[i] for i in Ingredients]) == 100
prob += lpSum([proteinPercent[i] * ingredient_vars[i] for i in Ingredients]) >= 8.0
prob += lpSum([fatPercent[i] * ingredient_vars[i] for i in Ingredients]) >= 6.0
prob += lpSum([fibrePercent[i] * ingredient_vars[i] for i in Ingredients]) <= 2.0
prob += lpSum([saltPercent[i] * ingredient_vars[i] for i in Ingredients]) <= 0.4

# 求解
prob.solve()
# 查看解的状态
print("Status:", LpStatus[prob.status])
# 查看解
for v in prob.variables():
    print(v.name, "=", v.varValue)

3.3 计算结果

Status: Optimal
Ingr_BEEF = 60.0
Ingr_CHICKEN = 0.0
Ingr_GEL = 40.0
Ingr_MUTTON = 0.0
Ingr_RICE = 0.0
Ingr_WHEAT = 0.0

参考文献

  1. 整数线性规划——pulp指南
  2. 优化模型(一)
  3. 使用python做线性规划求解
  4. The_Whiskas_Problem (猫粮配料比例问题)

标签:prob,pulp,线性规划,Ingredients,PULP,Pyhton,x2,x1,PuLP
From: https://www.cnblogs.com/haohai9309/p/17858544.html

相关文章

  • MATLAB热传导方程模型最小二乘法模型、线性规划对集成电路板炉温优化
    原文链接:https://tecdat.cn/?p=34230原文出处:拓端数据部落公众号分析师:LuoyanZhang集成电路板等电子产品生产中,控制回焊炉各部分保持工艺要求的温度对产品质量至关重要。通过分析炉温曲线,可以检查和改善产品生产质量,提高产量和解决生产问题。高效温度曲线测试系统的必要组件包......
  • 天池AI练习生计划 - 第一期Pyhton入门与实践 正式上线!通关赢取双重礼品!
    天池AI练习生养成计划是为天池入门学习用户准备的训练营,用户通关后可获得学习奖励,从学习者蜕变为AI新星!轻松来闯关,即可领取双重礼品~实训培训证书:通关两个关卡即可领取阿里云定制鼠标:通关全部关卡即可领取活动地址:https://tianchi.aliyun.com/specials/promotion/trainee活......
  • 代码随想训练营第十六天(Pyhton)| 104.二叉树的最大深度、 111.二叉树的最小深度、222.完
    104.二叉树的最大深度1、后续遍历递归法classSolution:defmaxDepth(self,root:Optional[TreeNode])->int:ifrootisNone:return0left_depth=self.maxDepth(root.left)#左right_depth=self.maxDepth(root.right)#......
  • 代码随想训练营第十三天(Pyhton)| 239. 滑动窗口最大值、347.前 K 个高频元素
    239.滑动窗口最大值classSolution:defmaxSlidingWindow(self,nums:List[int],k:int)->List[int]:res=[]tmp=MyQueue()foriinrange(k):tmp.push(nums[i])res.append(tmp.front())fo......
  • 数学建模__线性规划Python实现
    我使用到的是python库中scipy。'''线性规划'''#目标函数的系数#minz=2x1+3x2-5x3c=np.array([-2,-3,5])#不等式限制条件的系数,转化为小于等于#2x1-5x2+x3<=10,x1+3x2+x3<=12Aup=np.array([[-2,5,-1],[-1,-3,-1]])#必须是二维#右侧系数bup=np.array([-1......
  • 数学建模__非线性规划Python实现
    使用到的是scipy库线性规划指的是目标模型均为线性,除此以外的都是非线性规划,使用scipy提供的方法对该类问题进行求解。fromscipy.optimizeimportminimizeimportnumpyasnp#定义目标函数deffun(args):a,b,c,d=argsv=lambdax:(a+x[0])/(b+x[1])-c*x[0]......
  • 线性规划学习
    线性规划学习笔记\(1\)线性规划定义定义\(1.1\)\(\bullet\)已知一组实数\(a_1,a_2,\cdots,a_n\),以及一组变量\(x_1,x_2,\cdots,x_n\),在这些变量的一个线性函数定义为\(f(x_1,x_2,\cdots,x_n)=\sum_{i=1}\limits^na_ix_i\)。\(\bullet\)等式\(f(x_1,x_2,\cdots......
  • 推荐源哥和川川的新书:《Pyhton网络爬虫从入门到实战》
    ❤️作者主页:小虚竹❤️作者简介:大家好,我是小虚竹。2022年度博客之星评选TOP10......
  • 基于opencv-pyhton与opencv-c++的结合理解与学习
    2023年上半年,一直在学习opencv-c++版本,学习了其中的多个库函数笔记链接:https://www.cnblogs.com/Tan-code/category/2339311.htmlopencv-python读取图片,画圆等基本操作:opencv-c++多个库函数:opencv-python与opencv-c++结合理解:结合两段代码来比较实现:#导入所需模块......
  • pyhton解决高并发问题
    pyhton解决高并发问题#前端: 1.cdn加速,就是内容分发网络,简单来说就是把静态资源放到别的服务器上 2.精灵图:就是一个大的图片上面有多个我们需要的小图,用定位的方法,定位到不同的小图,满足我们的需求。这样一个请求拿到的图就可以用在多个位置。3.前端缓存:在返回的响应头里......