我已经设置了一个小脚本来描述在纸浆中的饮食优化解决方案。特别的整数并不是真正相关的,它们只是来自食物的宏。奇怪的是,当protein_ratio、carb_ratio或fat_ratio之一为0.1时,问题就变得不可行了。对于这些因素的其他组合(,应该总是加到1),这个问题有一个解决方案。有什么方法可以放松目标函数,使解有一个小的误差范围?例如,它不会给你带来800卡路里的食物,而是会给你带来810卡路里的食物。这仍然是可以接受的。下面是脚本:
from pulp import *
target_calories = 1500
protein_ratio = 0.4 #play around with this - 0.1 breaks it
carb_ratio = 0.4 #play around with this - 0.1 breaks it
fat_ratio = 0.2 #play around with this - 0.1 breaks it
problem = LpProblem("diet", sense = LpMinimize)
gramsOfMeat = LpVariable("gramsOfMeat", lowBound = 1)
gramsOfPasta = LpVariable("gramsOfPasta", lowBound = 1 )
gramsOfOil = LpVariable("gramsOfOil", lowBound = 1)
problem += gramsOfMeat*1.29 + gramsOfPasta*3.655 + gramsOfOil*9 - target_calories
totalprotein = gramsOfMeat*0.21 + gramsOfPasta*0.13 + gramsOfOil*0
totalcarb = gramsOfMeat*0 + gramsOfPasta*0.75 + gramsOfOil*0
totalfat = gramsOfMeat*0.05 + gramsOfPasta*0.015 + gramsOfOil*1
totalmacros = totalprotein + totalcarb + totalfat
problem += totalfat== fat_ratio*totalmacros
problem += totalcarb == carb_ratio*totalmacros
problem += totalprotein == protein_ratio*totalmacros
problem += gramsOfMeat*1.29 + gramsOfPasta*3.655 + gramsOfOil*9 - target_calories == 0
status = problem.solve()
print(status)
#assert status == pulp.LpStatusOptimal
#print(totalmacros)
print("Grams of meat: {}, grams of pasta: {}, grams of oil: {}, error: {}".format(value(gramsOfMeat), value(gramsOfPasta), value(gramsOfOil), value(problem.objective)))发布于 2019-05-06 00:46:06
你可以增加一个违反目标的惩罚。这样做的想法是引入两个新的决策变量,比如under和over,并添加如下约束
problem += gramsOfMeat*1.29 + gramsOfPasta*3.655 + gramsOfOil*9 - target_calories <= under
problem += target_calories - (gramsOfMeat*1.29 + gramsOfPasta*3.655 + gramsOfOil*9) <= over然后将您的目标函数更改为
problem += c_under * under + c_over * over其中c_under是单位在目标下的惩罚,c_over是超过的惩罚。(这些是参数。)如果要对over/U盘施加硬约束,可以添加新的约束:
problem += under <= max_under
problem += over <= max_over其中max_under和max_over是最大允许偏差(同样,参数)。
注意:你的模型有点奇怪,因为它没有真正的目标函数。通常,在饮食问题上,你想要最小化成本或最大化卡路里之类的东西,一般来说,在线性规划中,你想要最小化或最大化一些东西。在您的模型中,您只有约束。是的,有些东西看起来像一个目标函数--
problem += gramsOfMeat*1.29 + gramsOfPasta*3.655 + gramsOfOil*9 - target_calories--但是既然你把这个限制为0,它就不会有任何效果。没有目标函数当然没有什么不正确的,但这是不寻常的,我想提一下,以防这不是你想要的。
https://stackoverflow.com/questions/55996337
复制相似问题