简体   繁体   中英

Finding optimal weighted average

Constraints require multiplying every ingredient amount by the same factor where the nutrition of all ingredients combined must be within the minimum and maximum nutrition, whilst the optimal solution being the sum closest to the min/max median.

I've normalized the weight to be per gram, so to calculate the nutrients for an ingredient I do amount[g] * ingredients[2][nutrient] .

Ground beef nutrients sum:

calorie : 226.79616 * [ingredients][0][0] = 288.0311232
fat     : 226.79616 * [ingredients][0][1] = 22.679616
carb    : 226.79616 * [ingredients][0][2] = 0
protein : 226.79616 * [ingredients][0][3] = 19.470450336

All the ingredients nutrients combined results:

calorie: 575.8359139999999
fat: 48.160351846999994
carb: 3.842780537
protein: 37.289324852

scalingMin = 557.7/575.8359139999999 = 0.96850506618

scalingMax = 669.24/575.8359139999999 = 1.16220607942

The optimal scaling based on just the calorie would be 1.06453936807 , so all ingredients must be multiplied by the same scaling factor.

Here's the code I've written so far, but I'm not sure how to go about these constraints.

from ortools.linear_solver import pywraplp

# get nutrients sum
def getNutritionalSumOfAllIngredients(list):
  numbs = [type for type in range(0, 4)]
  for key, ingredient in enumerate(list):
    for type, nutrient in enumerate(ingredient[2]):
      numbs[type] += (ingredient[1] * nutrient)
  return numbs

def main():
  nutrients = [
    ['calorie', 557.7, 669.24],
    ['fat', 39.04, 51.43],
    ['carb', 0, 13],
    ['protein', 31.19, 41.59]
  ]

  # name, amount (grams), [calorie, fat, net_carbs, protein] weight per gram
  ingredients = [
    ['ground beef', 226.79616, [1.27, 0.1, 0, 0.08585000000000001]],
    ['salt', 6.083333333333333, [0, 0, 0, 0]],
    ['black pepper', 1.0374999999999999, [1.255 , 0.0163, 0.19325, 0.05195]],
    ['cajun seasoning', 4, [0.46604999999999996, 0.010249999999999999, 0.06565, 0.0191]],
    ['mozzarella cheese', 28.34952, [1.5, 0.11175, 0.01095, 0.11085]],
    ['cheddar cheese', 56.69904, [2.02, 0.16655, 0.015449999999999998, 0.11435000000000001]],
    ['butter', 14.1875, [3.585, 0.40555, 0.0003, 0.00425]],
    ['cooked bacon', 28, [2.74, 0.21635000000000001, 0.006750000000000001, 0.17864999999999998]]
  ]
  
  solver = pywraplp.Solver('ScaleIngredients', pywraplp.Solver.GLOP_LINEAR_PROGRAMMING)

  # # sum of all ingredients nutrition must be within each nutrients min/max i.e [557.7, 669.24, 'calorie']
  objectives = [solver.NumVar(item[1], item[2], item[0]) for item in nutrients]

  test = getNutritionalSumOfAllIngredients(ingredients)
  print(test)

CP-SAT is a pure integral solver. It only emulates continuous variables.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM