用线性规划解决配方问题
练习使用线性规划算法包解决猫粮配方的问题。
问题
某猫粮生产商生产猫粮时使用鸡肉、牛肉、羊肉、大米、小麦麦麸和凝胶作为原材料。这些原材料的营养成分的含量和价格如表所示。
物品 | 蛋白质 | 脂肪 | 纤维 | 盐 | 单价 |
---|---|---|---|---|---|
鸡肉 Chicken | 0.1 | 0.08 | 0.001 | 0.002 | 0.013 |
牛肉Beef | 0.2 | 0.1 | 0.005 | 0.005 | 0.008 |
羊肉Mutton | 0.15 | 0.11 | 0.003 | 0.007 | 0.01 |
大米Rice | 0 | 0.01 | 0.1 | 0.002 | 0.002 |
麦麸Wheat bran | 0.04 | 0.01 | 0.15 | 0.008 | 0.005 |
凝胶Gel | 0 | 0 | 0 | 0 | 0.001 |
成品要求(克/百克) | >=8 | >=6 | <=2 | <=0.4 |
- 成分单位: g/g
- 单价单位: 美元/g
- 成品中成分单位: g/100g
问:每100克产品中应如何配比原材料,才能在满足产品营养成分的情况下做到成本最小化?
下面练习使用线性规划pulp算法包解决此问题。
安装算法包
pulp源码地址:https://github.com/coin-or/pulp
pulp文档地址:https://coin-or.github.io/pulp/
pip install pulp
简化解题示例
- 假设只想用两种原料制作猫粮:鸡肉和牛肉
# 导入算法包
import pulp as pl
创建问题
- 使用
LpProblem
函数创建问题.LpProblem
有两个参数:- 第一个参数为问题的名称,可以是任意字符串
- 第二个参数为 LpMinimize(默认值) 或者 LpMaximize
# 创建问题
prob=pl.LpProblem("猫粮配方问题",pl.LpMinimize)
创建变量
- 使用
LpVariable
函数创建变量。LpVariable
有四个参数:name
:输出时使用的变量名,任意字符串lowBound
:变量下限,默认None
upBound
:变量上限,默认None
cat
:数据的属性,实质上是数据的类型(离散或者连续),可选:“pl.LpInterger”、“pl.LpBinary"或者"pl.LpContinuous”(默认)
# 创建变量
# 鸡肉百分比,最小值为0,最大值不限
x1=pl.LpVariable("鸡肉百分比",0,None)
# 牛肉百分比,最小值为0,最大值不限
x2=pl.LpVariable("牛肉百分比",0,None)
建立目标函数
- 目标函数结尾有一个逗号
,
,其后是一个简短的字符串来解释这个目标函数是干什么的
# 建立目标函数
prob+=0.013 * x1 + 0.008 * x2, "每罐产品的总成本"
建立约束
- 定义变量的时候已经包含了任意的非负约束
- 这再次使用“+=”运算符完成,因为我们正在向prob变量添加更多数据 。在此之后按逻辑输入约束,在约束方程的末尾加上一个逗号,并简要描述该约束的原因
# 5个约束条件需要输入
prob += x1 + x2 ==100,"每罐猫粮100克"
prob += 0.100 * x1 + 0.200 * x2 >= 8.0,"每100克猫粮的蛋白质含量必须不小于8克"
prob += 0.080 * x1 + 0.100 * x2 >= 6.0,"每100克猫粮的脂肪含量必须不小于6克"
prob += 0.001 * x1 + 0.005 * x2 <= 2.0,"每100克猫粮的纤维含量必须不大于2克"
prob += 0.002 * x1 + 0.005 * x2 <= 0.4,"每100克猫粮的食盐含量必须不大于0.4克"
解决问题
- 使用
solve()
函数计算问题 solve()
可以输入求解器参数。solve()
的返回值为解决问题的状态,{0: ‘Not Solved[未解决]’, 1: ‘Optimal[最佳]’, -1: ‘Infeasible[不可行]’, -2: ‘Unbounded[无界]’, -3: ‘Undefined[未定义]’}- 状态值保存在
.status
变量中 - 通过LpStatus查看状态的文字描述
- 定义的
x1
、x2
等变量的值保存在.variables()
中
# 解决问题
prob.solve()
print("状态:",pl.LpStatus[prob.status])
"""
打印输出为:
状态: Optimal
"""
# 输出变量值
for v in prob.variables():print(v.name,"=",v.varValue)
"""
打印输出为:
牛肉百分比 = 66.666667
鸡肉百分比 = 33.333333
"""
# 输出结果
print("每百克成品的成本价 = ",pl.value(prob.objective))
"""
打印输出为:
每百克成品的成本价 = 0.966666665
"""
完整的程序
# 导入算法包
import pulp as pl
# 创建问题
prob=pl.LpProblem("猫粮配方问题",pl.LpMinimize)
# 创建变量
# 鸡肉百分比,最小值为0,最大值不限
x1=pl.LpVariable("鸡肉百分比",0,None)
# 牛肉百分比,最小值为0,最大值不限
x2=pl.LpVariable("牛肉百分比",0,None)# 建立目标函数
prob+=0.013 * x1 + 0.008 * x2, "每罐产品的总成本"# 建立约束
# 5个约束条件需要输入
prob += x1 + x2 ==100,"每罐猫粮100克"
prob += 0.100 * x1 + 0.200 * x2 >= 8.0,"每100克猫粮的蛋白质含量必须不小于8克"
prob += 0.080 * x1 + 0.100 * x2 >= 6.0,"每100克猫粮的脂肪含量必须不小于6克"
prob += 0.001 * x1 + 0.005 * x2 <= 2.0,"每100克猫粮的纤维含量必须不大于2克"
prob += 0.002 * x1 + 0.005 * x2 <= 0.4,"每100克猫粮的食盐含量必须不大于0.4克"# 解决问题
prob.solve()
print("状态:",pl.LpStatus[prob.status])# 输出变量值
for v in prob.variables():print(v.name,"=",v.varValue)# 输出结果
print("每百克成品的成本价 = ",pl.value(prob.objective))
完整解题程序示例
import pulp as pl# 创建原料表
Ingredients = ["CHICKEN", "BEEF", "MUTTON", "RICE", "WHEAT", "GEL"]# 原材料成本单价(美元/克)
costs = {"CHICKEN": 0.013,"BEEF": 0.008,"MUTTON": 0.010,"RICE": 0.002,"WHEAT": 0.005,"GEL": 0.001,
}# 原材料中蛋白质的含量(g/g)
proteinPercent = {"CHICKEN": 0.100,"BEEF": 0.200,"MUTTON": 0.150,"RICE": 0.000,"WHEAT": 0.040,"GEL": 0.000,
}# 原材料中脂肪的含量(g/g)
fatPercent = {"CHICKEN": 0.080,"BEEF": 0.100,"MUTTON": 0.110,"RICE": 0.010,"WHEAT": 0.010,"GEL": 0.000,
}# 原材料中纤维的含量(g/g)
fibrePercent = {"CHICKEN": 0.001,"BEEF": 0.005,"MUTTON": 0.003,"RICE": 0.100,"WHEAT": 0.150,"GEL": 0.000,
}# 原材料中盐分的含量(g/g)
saltPercent = {"CHICKEN": 0.002,"BEEF": 0.005,"MUTTON": 0.007,"RICE": 0.002,"WHEAT": 0.008,"GEL": 0.000,
}
创建问题
# 创建问题
prob = pl.LpProblem("猫粮配方问题",pl.LpMinimize)
创建变量
- 使用
LpVariable.dicts()
集中创建变量,参数:name
:字符串,变量名称的前缀indexs
:字符串list,变量(一般是原材料名)的名称列表lowBound
:变量下限,默认None
upBound
:变量上限,默认None
cat
:数据的属性,实质上是数据的类型(离散或者连续),可选:“pl.LpInterger”、“pl.LpBinary"或者"pl.LpContinuous”(默认)
ingredient_vars = pl.LpVariable.dicts("Ingr",Ingredients,0)
print(ingredient_vars)
打印出来的变量结果为:
{'CHICKEN': Ingr_CHICKEN, 'BEEF': Ingr_BEEF, 'MUTTON': Ingr_MUTTON, 'RICE': Ingr_RICE, 'WHEAT': Ingr_WHEAT, 'GEL': Ingr_GEL}
创建目标函数
#创建目标函数
prob += pl.lpSum([costs[i]*ingredient_vars[i] for i in Ingredients])
创建约束
#添加约束条件
# 所有参数的和为100
prob += pl.lpSum([ingredient_vars[i] for i in Ingredients]) == 100
# 每100克猫粮的蛋白质含量必须不小于8克
prob += pl.lpSum([proteinPercent[i] * ingredient_vars[i] for i in Ingredients]) >= 8.0
# 每100克猫粮的脂肪含量必须不小于6克
prob += pl.lpSum([fatPercent[i] * ingredient_vars[i] for i in Ingredients]) >= 6.0
# 每100克猫粮的纤维含量必须不大于2克
prob += pl.lpSum([fibrePercent[i] * ingredient_vars[i] for i in Ingredients]) <= 2.0
# 每100克猫粮的盐分含量必须不大于0.4克
prob += pl.lpSum([saltPercent[i] * ingredient_vars[i] for i in Ingredients]) <= 0.4
解决问题
# 解决问题
prob.solve()
print("状态:",pl.LpStatus[prob.status])
"""
打印输出为:
状态: Optimal
"""
# 输出变量值
for i in Ingredients:print(ingredient_vars[i],"=",ingredient_vars[i].value())
"""
打印输出为:
Ingr_CHICKEN = 0.0
Ingr_BEEF = 60.0
Ingr_MUTTON = 0.0
Ingr_RICE = 0.0
Ingr_WHEAT = 0.0
Ingr_GEL = 40.0
"""
# 输出结果
print("每百克成品的成本价 = ",pl.value(prob.objective))
"""
打印输出为:
每百克成品的成本价 = 0.52
"""
完整的程序
# 导入包
import pulp as pl# 创建原料表
Ingredients = ["CHICKEN", "BEEF", "MUTTON", "RICE", "WHEAT", "GEL"]# 原材料成本单价(美元/克)
costs = {"CHICKEN": 0.013,"BEEF": 0.008,"MUTTON": 0.010,"RICE": 0.002,"WHEAT": 0.005,"GEL": 0.001,
}# 原材料中蛋白质的含量(g/g)
proteinPercent = {"CHICKEN": 0.100,"BEEF": 0.200,"MUTTON": 0.150,"RICE": 0.000,"WHEAT": 0.040,"GEL": 0.000,
}# 原材料中脂肪的含量(g/g)
fatPercent = {"CHICKEN": 0.080,"BEEF": 0.100,"MUTTON": 0.110,"RICE": 0.010,"WHEAT": 0.010,"GEL": 0.000,
}# 原材料中纤维的含量(g/g)
fibrePercent = {"CHICKEN": 0.001,"BEEF": 0.005,"MUTTON": 0.003,"RICE": 0.100,"WHEAT": 0.150,"GEL": 0.000,
}# 原材料中盐分的含量(g/g)
saltPercent = {"CHICKEN": 0.002,"BEEF": 0.005,"MUTTON": 0.007,"RICE": 0.002,"WHEAT": 0.008,"GEL": 0.000,
}# 创建问题
prob = pl.LpProblem("猫粮配方问题",pl.LpMinimize)# 创建变量
ingredient_vars = pl.LpVariable.dicts("Ingr",Ingredients,0)#创建目标函数
prob += pl.lpSum([costs[i]*ingredient_vars[i] for i in Ingredients])#添加约束条件
# 所有参数的和为100
prob += pl.lpSum([ingredient_vars[i] for i in Ingredients]) == 100
# 每100克猫粮的蛋白质含量必须不小于8克
prob += pl.lpSum([proteinPercent[i] * ingredient_vars[i] for i in Ingredients]) >= 8.0
# 每100克猫粮的脂肪含量必须不小于6克
prob += pl.lpSum([fatPercent[i] * ingredient_vars[i] for i in Ingredients]) >= 6.0
# 每100克猫粮的纤维含量必须不大于2克
prob += pl.lpSum([fibrePercent[i] * ingredient_vars[i] for i in Ingredients]) <= 2.0
# 每100克猫粮的盐分含量必须不大于0.4克
prob += pl.lpSum([saltPercent[i] * ingredient_vars[i] for i in Ingredients]) <= 0.4# 解决问题
prob.solve()
print("状态:",pl.LpStatus[prob.status])# 输出变量值
for i in Ingredients:print(ingredient_vars[i],"=",ingredient_vars[i].value())# 输出结果
print("每百克成品的成本价 = ",pl.value(prob.objective))
参考资料
https://coin-or.github.io/pulp/CaseStudies/a_blending_problem.html
用线性规划解决配方问题相关推荐
- 基于MATLAB的线性规划解决方法——单纯形法
基于MATLAB的线性规划解决方法--单纯形法 简介 基本思想 基本原理 具体实例 初等行变换 获取初始检验数 单纯形表原理函数 简介 本文主要介绍采用单纯形表解决线性规划问题(LP),将单纯形表中的 ...
- 算法实验之线性规划解决配料问题
公式和图片不显示... 1 问题描述 食谱/配料问题:设有n种配料,每种配料含有m种营养成分,用 表示一个单位的第 j (j<=n)种配料中含有的第 i (i<=m)种营养成分数量,用 表 ...
- 数据科学家线性规划入门指南
前言 生活之道在于优化.每个人拥有的资源和时间都是有限的,我们都想充分利用它们.从有效地利用个人时间到解决公司的供应链问题--处处都有用到优化. 优化还是一个有趣的课题--它解决的问题初看十分简单,但 ...
- Matlab 整数线性规划问题模型代码
整数线性规划问题的基本内容 整数线性规划解决的是自变量在一定的线性约束条件下,使得线性目标函数求得最大值或者最小值的问题.其中自变量只能取整数.特别地,当自变量只能取0或者1时,称之为 0-1 整数规 ...
- Matlab 线性规划问题模型代码
线性规划问题的基本内容 线性规划解决的是自变量在一定的线性约束条件下,使得线性目标函数求得最大值或者最小值的问题. \[ \min z=\sum_{j=1}^{n} f_{j} x_{j} \] \[ ...
- 万字教你如何用 Python 实现线性规划
摘要:线性规划是一组数学和计算工具,可让您找到该系统的特定解,该解对应于某些其他线性函数的最大值或最小值. 本文分享自华为云社区<实践线性规划:使用 Python 进行优化>,作者: Yu ...
- 基于JMP公差设计探索稳健性的配方和工艺
DOE在新药或者仿制药设计与研发过程中,往往会分为三个阶段:系统设计.参数设计和容差设计(也叫公差设计,20世纪70年代,由田口玄一提出)进行.今天我们就来看看如何通过这三个阶段实现稳健的配方和工艺. ...
- 只需一步,轻松用Python实现线性规划
线性规划说明 什么是线性规划? 想象一下,您有一个线性方程组和不等式系统.这样的系统通常有许多可能的解决方案.线性规划是一组数学和计算工具,可让您找到该系统的特定解,该解对应于某些其他线性函数的最大值 ...
- 【Python】用 Python 的 scipy 包实现线性规划(LP)
文章目录 一.线性规划(linear programming,LP) 二.用 python 实现线性规划 1. 方法:使用 scipy 包中的 optimize.linprog 2. 实例 参考链接 ...
最新文章
- 基于癌症基因组学数据的miRNA 功能模块识别算法研究
- 字符串反转python_Python 反转字符串(reverse)的方法小结
- JZOJ__Day 6:【普及模拟】Oliver的成绩(score)
- Java学习笔记二:数据类型
- 使用Nginx反向代理和proxy_cache缓存搭建CDN服务器加快Web访问速度
- [USACO13JAN] Cow Lineup (单调队列,尺取法)
- 文件管理系统_Python学习第170节--Linux文件管理系统实际操作和具体介绍
- python的gui编程pyqt5_Python-GUI编程-PyQt5
- cas如何实现多系统间的相互认证_统一身份认证和单点登录的区别
- Python 集合定义及运算
- 工字型钢弹性截面模量计算公式_截面抗弯模量的公式
- CryEngine架构概览
- 用HTML+CSS简单做了张简历表格
- 2021年度软件企业 100 强榜单(附全名单)看看有你家公司没
- Android Camera2教程之打开相机、开启预览、实现PreviewCallback、拍照
- c语言程序设计拉丁方阵结构图,C语言实例之拉丁方阵
- Windows Linux对应软件
- main函数带有参数
- 【技巧】去掉RedisDesktopManager更新提示弹窗
- html图片添加阴影效果图,使用css给图片添加阴影入门篇
热门文章
- python数学公式代码_PythonStudy_‘数学公式计算器’代码
- 调整DOSBox的窗口大小:跨过三连坑
- AndroidFragment仿写美团外卖界面
- 安装Tensorflow 报错false Not creating XLA devices, tf_xla_enable_xla_devices not set
- python编程一级考试报名_2021年的第一场考试!全国青少年编程等级考试开始报名!...
- Win7系统专业版调整屏幕亮度的详细教程--win7w.com
- 建行浙江分行总部【等。。。】
- ubuntu uninstall
- python朋友圈可见_女神说不能每张照片P的同样,因此朋友圈开三天可见,用Python一步解决...
- mysql-使用Navicat导出sql查询数据