У меня есть следующая таблица, из которой нужно создать рецепт с определенным значением для белков и углеводов.
И используя or-tools для решения этой проблемы, пока у меня есть:
Форматированные данные
data = [
['f1', 10, 15, 17, 10],
['f2', 2, 11, 12, 14],
['f3', 6.5, 17, 16, 13],
['f4', 8, 12, 8, 16]
]
Ограничения для нутриентов:
питательные вещества = [["белок", 15,5], ["углеводы", 12,3]]
Целевая функция, где верхняя граница "data i"- запас этого конкретного элемента.
food = [[]] * len(data)
# Objective: minimize the sum of (price-normalized) foods.
objective = solver.Objective()
for i in range(0, len(data)):
food[i] = solver.NumVar(0.0, data[i][1], data[i][0])
objective.SetCoefficient(food[i], 4)
objective.SetMinimization()
У меня также есть как ограничить требуемое значение каждого питательного вещества:
constraints = [0] * (len(nutrients))
for i in range(0, len(nutrients)):
constraints[i] = solver.Constraint(nutrients[i][1], solver.infinity())
for j in range(0, len(data)):
constraints[i].SetCoefficient(food[j], data[j][i+3])
И, наконец, решатель:
status = solver.Solve ()
if status == solver.OPTIMAL:
# Display the amounts (in dollars) to purchase of each food.
price = 0
num_nutrients = len(data[i]) - 3
nutrients = [0] * (len(data[i]) - 3)
for i in range(0, len(data)):
price += food[i].solution_value()
for nutrient in range(0, num_nutrients):
nutrients[nutrient] += data[i][nutrient+3] * food[i].solution_value()
if food[i].solution_value() > 0:
print ("%s = %f" % (data[i][0], food[i].solution_value()))
print ('Optimal price: $%.2f' % (price))
else: # No optimal solution was found.
if status == solver.FEASIBLE:
print ('A potentially suboptimal solution was found.')
else:
print ('The solver could not solve the problem.')
Что до этой части работает нормально, я получаю следующий результат:
f1 = 0.077049
f3 = 0.886885
Optimal price: $0.96
Знайте, что мне нужно добавить также ограничения на количество кг, которое я сделаю, которые также должны удовлетворять предыдущим ограничениям.
Моим первым предположением было добавить множитель к требованию к питательным веществам
factor = 10
nutrients = [
["protein",15.5*factor],
["carbohydrates",12.3*factor]]
Таким образом, у меня будет в 10 раз больше еды, но потом я понял, что это неправильно, так какпотребность в концентрации EG
Мне нужно 10 кг с 15,5 белка / кг и 12,3 углеводов / кг. Необходимое ограничение выглядит примерно так:
(f1*W + f2*X + f3*Y + f4*Z)/(W+X+Y+Z) = 10kg with 15.5 protein/kg and 12.3 carbohydrates/kg
Where W, X, Y and Z are the kg of each food
Как добавить это ограничение в решатель?