我需要对我的一个字典的值部分应用约束,我使用 Pulp 来解决优化问题。我有一个食品数据,其中包含食品项目信息以及它们的营养信息和每份/份成本。
我的代码工作正常,为我提供了每种食物的份量并最大限度地降低了成本。我需要对每个食品数量应用一个过滤器,其中 n 是要消费的特定食品的数量。
数据参考
from pulp import *
import pandas as pd
prob = LpProblem("Simple Diet Problem", LpMinimize)
df = pd.read_excel("diet - medium.xls", nrows=17)
food_items = list(df['Foods'])
costs = dict(zip(food_items, df['Price/Serving']))
calories = dict(zip(food_items, df['Calories']))
fat = dict(zip(food_items, df['Total_Fat (g)']))
carbs = dict(zip(food_items, df['Carbohydrates (g)']))
food_vars = LpVariable.dicts("Food", food_items, lowBound=0, cat='Continuous')
prob += lpSum([costs[i] * food_vars[i] for i in food_items])
prob += lpSum([calories[f] * food_vars[f] for f in food_items]) >= 800.0
prob += lpSum([calories[f] * food_vars[f] for f in food_items]) <= 1300.0
# Need to apply constraint for number of each items to be consumed
prob.solve()
print("Status:", LpStatus[prob.status])
for v in prob.variables():
if v.varValue > 0:
print(v.name, "=", v.varValue)
obj = value(prob.objective)
print("The total cost of this balanced diet is: ${}".format(round(obj, 2)))
您需要执行以下操作:
-
创建列标题列表 - 将用于创建约束的所有因素:
factors = [] for col in data.columns: factors.append(col)
然后,您将创建字典字典, 其中每个因素都是一个键,其中包含食物项目的嵌套字典和相应的数量
my_dict = {} for i,j in enumerate(factors): my_dict[j] = {x[0]: x[i+1] for x in data_list}
在这里要小心切片;确保您了解哪些列是行名,哪些列是数据的开头。
创建一个带有mins和maxes的字典;这是我的例子:
constraints = pd.read_excel("diet_large.xls") constraints = constraints[7147:7149] constraints = constraints.values.tolist() mins = constraints[0][1:] maxs = constraints[1][1:] min_dict = dict(zip(factors, mins)) max_dict = dict(zip(factors, maxs))
最后,您将设置目标函数和约束函数。下面我只是发布约束:
for i in factors: prob += lpSum([my_dict[i][b] * amountVars[b] for b in food]) >= min_dict[i], "" prob += lpSum([my_dict[i][b] * amountVars[b] for b in food]) <= max_dict[i], ""
理解正确,您是在询问如何在循环中添加约束,而不是一个接一个地添加约束。如果是这样,一般方法是这样的:
for f in food_items:
prob += food_vars[f] <= max_qty[f]
其中max_qty[f]
是食物f
的最大允许量,从您的 CSV 文件中读取。