寻找最佳加权平均值

问题描述

约束条件要求将每种成分 amount 乘以相同的系数,其中所有成分的营养组合必须在最小和最大营养范围内,而最佳解决方案是最接近最小/最大中位数的总和。

>

我已将重量标准化为每克,因此为了计算一种成分的营养成分,我amount[g] * ingredients[2][nutrient]

碎牛肉营养总和:

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

所有成分营养组合结果:

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

仅基于卡路里的最佳比例是 1.06453936807,因此所有成分必须乘以相同的比例因子。

这是我目前编写的代码,但我不确定如何处理这些约束。

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',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.08585000000000001]],['salt',6.083333333333333,[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 是一个纯积分求解器。它只模拟连续变量。