练习使用线性规划算法包解决猫粮配方的问题。

问题

某猫粮生产商生产猫粮时使用鸡肉、牛肉、羊肉、大米、小麦麦麸和凝胶作为原材料。这些原材料的营养成分的含量和价格如表所示。

物品 蛋白质 脂肪 纤维 单价
鸡肉 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有两个参数:

    1. 第一个参数为问题的名称,可以是任意字符串
    2. 第二个参数为 LpMinimize(默认值) 或者 LpMaximize
# 创建问题
prob=pl.LpProblem("猫粮配方问题",pl.LpMinimize)

创建变量

  • 使用LpVariable函数创建变量。LpVariable有四个参数:

    1. name:输出时使用的变量名,任意字符串
    2. lowBound:变量下限,默认None
    3. upBound:变量上限,默认None
    4. 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查看状态的文字描述
  • 定义的x1x2等变量的值保存在.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()集中创建变量,参数:

    1. name:字符串,变量名称的前缀
    2. indexs:字符串list,变量(一般是原材料名)的名称列表
    3. lowBound:变量下限,默认None
    4. upBound:变量上限,默认None
    5. 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

用线性规划解决配方问题相关推荐

  1. 基于MATLAB的线性规划解决方法——单纯形法

    基于MATLAB的线性规划解决方法--单纯形法 简介 基本思想 基本原理 具体实例 初等行变换 获取初始检验数 单纯形表原理函数 简介 本文主要介绍采用单纯形表解决线性规划问题(LP),将单纯形表中的 ...

  2. 算法实验之线性规划解决配料问题

    公式和图片不显示... 1 问题描述 食谱/配料问题:设有n种配料,每种配料含有m种营养成分,用 表示一个单位的第 j (j<=n)种配料中含有的第 i (i<=m)种营养成分数量,用 表 ...

  3. 数据科学家线性规划入门指南

    前言 生活之道在于优化.每个人拥有的资源和时间都是有限的,我们都想充分利用它们.从有效地利用个人时间到解决公司的供应链问题--处处都有用到优化. 优化还是一个有趣的课题--它解决的问题初看十分简单,但 ...

  4. Matlab 整数线性规划问题模型代码

    整数线性规划问题的基本内容 整数线性规划解决的是自变量在一定的线性约束条件下,使得线性目标函数求得最大值或者最小值的问题.其中自变量只能取整数.特别地,当自变量只能取0或者1时,称之为 0-1 整数规 ...

  5. Matlab 线性规划问题模型代码

    线性规划问题的基本内容 线性规划解决的是自变量在一定的线性约束条件下,使得线性目标函数求得最大值或者最小值的问题. \[ \min z=\sum_{j=1}^{n} f_{j} x_{j} \] \[ ...

  6. 万字教你如何用 Python 实现线性规划

    摘要:线性规划是一组数学和计算工具,可让您找到该系统的特定解,该解对应于某些其他线性函数的最大值或最小值. 本文分享自华为云社区<实践线性规划:使用 Python 进行优化>,作者: Yu ...

  7. 基于JMP公差设计探索稳健性的配方和工艺

    DOE在新药或者仿制药设计与研发过程中,往往会分为三个阶段:系统设计.参数设计和容差设计(也叫公差设计,20世纪70年代,由田口玄一提出)进行.今天我们就来看看如何通过这三个阶段实现稳健的配方和工艺. ...

  8. 只需一步,轻松用Python实现线性规划

    线性规划说明 什么是线性规划? 想象一下,您有一个线性方程组和不等式系统.这样的系统通常有许多可能的解决方案.线性规划是一组数学和计算工具,可让您找到该系统的特定解,该解对应于某些其他线性函数的最大值 ...

  9. 【Python】用 Python 的 scipy 包实现线性规划(LP)

    文章目录 一.线性规划(linear programming,LP) 二.用 python 实现线性规划 1. 方法:使用 scipy 包中的 optimize.linprog 2. 实例 参考链接 ...

最新文章

  1. 基于癌症基因组学数据的miRNA 功能模块识别算法研究
  2. 字符串反转python_Python 反转字符串(reverse)的方法小结
  3. JZOJ__Day 6:【普及模拟】Oliver的成绩(score)
  4. Java学习笔记二:数据类型
  5. 使用Nginx反向代理和proxy_cache缓存搭建CDN服务器加快Web访问速度
  6. [USACO13JAN] Cow Lineup (单调队列,尺取法)
  7. 文件管理系统_Python学习第170节--Linux文件管理系统实际操作和具体介绍
  8. python的gui编程pyqt5_Python-GUI编程-PyQt5
  9. cas如何实现多系统间的相互认证_统一身份认证和单点登录的区别
  10. Python 集合定义及运算
  11. 工字型钢弹性截面模量计算公式_截面抗弯模量的公式
  12. CryEngine架构概览
  13. 用HTML+CSS简单做了张简历表格
  14. 2021年度软件企业 100 强榜单(附全名单)看看有你家公司没
  15. Android Camera2教程之打开相机、开启预览、实现PreviewCallback、拍照
  16. c语言程序设计拉丁方阵结构图,C语言实例之拉丁方阵
  17. Windows Linux对应软件
  18. main函数带有参数
  19. 【技巧】去掉RedisDesktopManager更新提示弹窗
  20. html图片添加阴影效果图,使用css给图片添加阴影入门篇

热门文章

  1. python数学公式代码_PythonStudy_‘数学公式计算器’代码
  2. 调整DOSBox的窗口大小:跨过三连坑
  3. AndroidFragment仿写美团外卖界面
  4. 安装Tensorflow 报错false Not creating XLA devices, tf_xla_enable_xla_devices not set
  5. python编程一级考试报名_2021年的第一场考试!全国青少年编程等级考试开始报名!...
  6. Win7系统专业版调整屏幕亮度的详细教程--win7w.com
  7. 建行浙江分行总部【等。。。】
  8. ubuntu uninstall
  9. python朋友圈可见_女神说不能每张照片P的同样,因此朋友圈开三天可见,用Python一步解决...
  10. mysql-使用Navicat导出sql查询数据