Как бороться с несовместимым целлюлозным раствором в зависимости от конкретных входов? - PullRequest
0 голосов
/ 05 мая 2019

Я установил небольшой скрипт, который описывает решение по оптимизации диеты в мякоти.Конкретные целые числа на самом деле не актуальны, они просто макросы из продуктов.Странно то, что когда один из параметров 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)))

1 Ответ

1 голос
/ 06 мая 2019

Вы можете добавить штраф за нарушение цели. Идея состояла бы в том, чтобы ввести две новые переменные решения, скажем 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 - штраф за превышение. (Это параметры.) Если вы хотите наложить жесткую границу на верх / низ, вы можете добавить новые ограничения:

problem += under <= max_under
problem += over <= max_over

, где max_under и max_over - максимально допустимые отклонения (опять же, параметры).

Одно замечание: ваша модель немного странная, потому что на самом деле она не имеет целевой функции. Обычно в проблеме диеты вы хотите минимизировать затраты или максимизировать калории или что-то в этом роде, и в целом в линейном программировании вы хотите минимизировать или максимизировать что-то. В вашей модели у вас есть только ограничения. Правда, есть нечто, похожее на целевую функцию -

problem += gramsOfMeat*1.29 + gramsOfPasta*3.655 + gramsOfOil*9 - target_calories

- но поскольку вы ограничили это значение равным 0, это на самом деле не имеет никакого эффекта. Конечно, нет ничего неправильного в отсутствии целевой функции, но это необычно, и я хотел бы упомянуть об этом на случай, если это не то, что вы намеревались.

...