python Pulp求解线性规划问题(含实例)

问题描述

在这里插入图片描述
上图所示的Whiskas猫粮由Ben生产。Ben希望尽可能便宜地生产其猫粮,同时确保它们满足罐头上所示的规定的营养分析要求。因此,他们希望改变每种成分的使用量(主要成分是鸡肉,牛肉,羊肉,大米,小麦和凝胶),同时仍要满足其营养标准。
在这里插入图片描述
鸡肉,牛肉和羊肉的成本分别为0.013美元,0.008美元和0.010美元,而大米,小麦和凝胶的成本分别为0.002美元,0.005美元和0.001美元。(所有成本均为每克。)在此练习中,我们将忽略维生素和矿物质成分。(无论如何,这些的任何费用都可能很小。)

每种成分都有助于最终产品中蛋白质,脂肪,纤维和盐的总重量。下表列出了每克成分的贡献(以克计)。

东西蛋白脂肪纤维
0.1000.0800.0010.002
牛肉0.2000.1000.0050.005
羊肉0.1500.1100.0030.007
白饭0.0000.0100.1000.002
麦麸0.0400.0100.1500.008
凝胶0.0000.0000.0000.000

简化模型的建立

首先,我们将考虑一个简化的问题,以构建一个简单的Python模型。

定义决策变量

假设Whiskas希望仅使用两种成分制作猫食:鸡肉和牛肉。我们将首先定义决策变量:

  • x1 = 一罐猫粮中鸡肉的百分比
  • x2 = 一罐猫粮中牛肉的比例
制定目标函数
  • min 0.013x1+0.008x2
约束条件

这些变量的约束条件是它们必须总计为100,并且满足营养要求:

			1.000x1 + 1.000x2 = 100.0
			0.100x1 + 0.200x2 >= 8.0
			0.080x1 + 0.100x2 >= 6.0
			0.001x1 + 0.005x2 <= 2.0
			0.002x1 + 0.005x2 <= 0.4
解决方案

要获得此线性程序的解决方案,我们可以使用Python编写一个简短的程序来调用PuLP的建模函数,然后将其调用求解器。这将逐步解释如何编写此Python程序。

pulp.LpProblem(name='NoName', sense=LpMinimize),用来建立优化问题,其函数的参数为name:
在lp文件中写入的问题名称;sense:最大或者最小,可为LpMinimize\LpMaximize二者之一。

pulp.LpVariable(name, lowBound=None, upBound=None, cat='Continuous', e=None),其函数参数为name:
变量名;lowBound变量下界;upBound变量上界;cat变量类型,可以为LpInteger\LpBinary\LpContinuous三者之一;
e指明变量是否在目标函数和约束中存在,主要用来实现列生成算法。

例如:
LpVariable(“example”, None, 100)
或LpVariable(“example”, upBound = 100)

  • 针对此问题的Code
# 1. 建立问题
prob = LpProblem("Bleding Problem", LpMinimize)

# 2. 建立变量
x1 = LpVariable("ChickenPercent", 0, None, LpInteger)
x2 = LpVariable("BeefPercent", 0)

# 3. 设置目标函数
prob += 0.013*x1 + 0.008*x2, "Total Cost of Ingredients per can"

# 4. 施加约束
prob += x1 + x2 == 100, "PercentagesSum"
prob += 0.100*x1 + 0.200*x2 >= 8.0, "ProteinRequirement"
prob += 0.080*x1 + 0.100*x2 >= 6.0, "FatRequirement"
prob += 0.001*x1 + 0.005*x2 <= 2.0, "FibreRequirement"
prob += 0.002*x2 + 0.005*x2 <= 0.4, "SaltRequirement"

# 5.求解
prob.solve()

# 6.打印求解状态
print("Status:",LpStatus[prob.status])

# 7. 打印出每个变量的最优值
for v in prob.variables():
    print(v.name, "=", v.varValue)

# 打印最优解的目标函数值
print("Total Cost of Ingredient per can = ", value(prob.objective))

全模型建立

现在,我们将使用所有变量完全解决问题。尽管可以在上面的方法中添加很少的内容来将其实现到Python中,但我们将寻找一种更好的方法,该方法不将问题数据和公式混为一谈。这将使更改其他测试的任何问题数据变得更加容易。我们将通过代数定义问题开始相同的方法:

定义决策变量
确定Whiskas猫食问题的决策变量决策变量是我们罐头中所含不同成分的百分比。
由于罐头为100克,因此这些百分比还代表所含每种成分的克含量。
我们必须正式定义决策变量,并确保陈述我们使用的单位。
  • x1 = 一罐猫粮中鸡肉的比例
  • x2 = 一罐猫粮中牛肉的比例
  • x3 = 一罐猫粮中羊肉的比例
  • x4 = 一罐猫粮中白饭的比例
  • x5 = 一罐猫粮中麦麸的比例
  • x6 = 一罐猫粮中凝胶 的比例
制定目标函数
制定Whiskas猫食问题的目标函数,目的是使每罐猫食的成分总成本最小化。我们知道每种成分每克的成本。我们确定每种成分在罐中的百分比,因此我们必须除以100,再乘以以g为单位的罐的重量。这将使我们获得每种成分的重量(克)
  • min 0.013x1+0.008x2 + 0.010x3 + 0.002x4 + 0.005x5 + 0.001x6
约束条件
制定约束Whiskas猫粮问题的约束是:
百分比之和必须组成整个罐(= 100%)。
满足规定的营养分析要求。
“整个罐头”的约束是:
  • x1 + x2 + x3 + x4 + x5 + x6 = 100
为了满足营养分析的要求,每100克中至少要有8克蛋白质,6克脂肪,但不超过2克纤维和0.4克盐。
为了制定这些约束条件,我们利用了每种成分的上一个贡献表。这使我们能够对成分中蛋白质,
脂肪,纤维和盐的总贡献制定以下约束条件:
  • 0.100x1 + 0.200x2 + 0.150x3 + 0.000x4 + 0.040x5 + 0.0x6 >= 8.0
  • 0.080x1 + 0.100x2 + 0.110x3 + 0.010x4 + 0.010x5 + 0.0x6 >= 6.0
  • 0.001x1 + 0.005x2 + 0.003x3 + 0.100x4 + 0.150x5 + 0.0x6 <= 2.0
  • 0.002x1 + 0.005x2 + 0.007x3 + 0.002x4 + 0.008x5 + 0.0x6 <= 0.4
解决方案
在prob定义问题的变量或类型之前,将关键问题数据输入字典。其中包括成分列表,其次是每种成分的成本,
以及四种营养素中每种成分的百分比。这些值是明确列出的,对编程知识很少的人很容易更改。成分是参考键
,数字作为数据。
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)

# Create the 'prob' variable to contain the problem data
prob = LpProblem("The Whiskas Problem", LpMinimize)

# A dictionary called 'ingredient_vars' is created to contain the referenced Variables
ingredient_vars = LpVariable.dicts("Ingr",Ingredients,0)

prob += lpSum([costs[i]*ingredient_vars[i] for i in Ingredients]), "Total Cost of Ingredients per can"

# The five constraints are added to 'prob'
prob += lpSum([ingredient_vars[i] for i in Ingredients]) == 100, "PercentagesSum"
prob += lpSum([proteinPercent[i] * ingredient_vars[i] for i in Ingredients]) >= 8.0, "ProteinRequirement"
prob += lpSum([fatPercent[i] * ingredient_vars[i] for i in Ingredients]) >= 6.0, "FatRequirement"
prob += lpSum([fibrePercent[i] * ingredient_vars[i] for i in Ingredients]) <= 2.0, "FibreRequirement"
prob += lpSum([saltPercent[i] * ingredient_vars[i] for i in Ingredients]) <= 0.4, "SaltRequirement"

# 此后代码和前面相同,这里略写
附上pulp官网来链接
  • 10
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值