匹配每日宏量营养素目标的食材分量平衡算法选型问询
Great question! This is a classic constrained optimization problem—perfect for linear programming (if you want to hit your macro targets exactly, when possible) or weighted least squares (if you just want the closest match when exact targets aren’t feasible). Let’s break it down:
一、算法选择:两种核心思路
1. 线性规划(Exact Targets)
If your goal is to hit the exact 220g protein / 60g fat / 230g carbs (assuming your ingredients can combine to make that happen), this is a standard linear programming problem:
- Variables: Let ( x_i ) represent how many 100g servings you need of each ingredient (e.g., ( x_1 ) = chicken breast servings)
- Constraints:
- Protein total: ( 23.1x_1 + 0.9x_2 + 0.9x_3 + 0x_4 +7.5x_5 = 220 )
- Fat total: ( 1.2x_1 +11.4x_2 +0x_3 +100x_4 +2.4x_5 =60 )
- Carbs total: ( 0x_1 +0.2x_2 +11.5x_3 +0x_4 +74x_5 =230 )
- All ( x_i \geq 0 ) (you can’t eat negative amounts of food!)
- Objective: If there are multiple solutions, you can prioritize minimizing total weight, cost, or another metric.
2. Weighted Least Squares (Closest Match)
More often, exact targets might not be possible with your ingredient list. For this, use least squares optimization to minimize the gap between your actual macros and the target:
- Objective Function: Minimize the squared difference between actual and target macros. You can add weights if some macros matter more (e.g., double the weight of protein if it’s your top priority):
[
\text{Loss} = w_p*(P_{actual}-220)^2 + w_f*(F_{actual}-60)^2 + w_c*(C_{actual}-230)^2
] - Constraint: Still ( x_i \geq 0 ) (no negative servings)
二、现成 Tools & Libraries
You don’t need to code these algorithms from scratch—here’s what to use, depending on your language:
- Swift (matching your sample code):
- Look for Swift-based numerical optimization libraries that support constrained linear programming or least squares. Apple’s
Numericsframework provides building blocks for matrix operations, which you can combine with custom constraint handling.
- Look for Swift-based numerical optimization libraries that support constrained linear programming or least squares. Apple’s
- Python (for quick testing/validation):
scipy.optimize.linprog: Solves linear programming problems with non-negative constraints.scipy.optimize.least_squares: Ideal for the "closest match" scenario, with built-in support for bounds (like ( x_i \geq 0 )).
Here’s a quick Python example to demonstrate the least squares approach:
import numpy as np from scipy.optimize import least_squares # Macros per 100g: [protein, fat, carbs] macros = np.array([ [23.1, 1.2, 0], # Chicken breast [0.9, 11.4, 0.2], # Carrots [0.9, 0, 11.5], # Onions [0, 100, 0], # Grape seed oil [7.5, 2.4, 74] # Brown rice ]) target_macros = np.array([220, 60, 230]) # Calculate the difference between actual and target macros def macro_error(servings): actual = macros.T @ servings # Multiply servings by macro matrix return actual - target_macros # Start with a guess of 1 serving of each ingredient initial_guess = np.ones(5) # Solve with non-negative serving constraints result = least_squares(macro_error, initial_guess, bounds=(0, np.inf)) # Print results print("Servings (100g each):", result.x.round(2)) actual = macros.T @ result.x print(f"Actual macros:\nProtein: {actual[0]:.1f}g\nFat: {actual[1]:.1f}g\nCarbs: {actual[2]:.1f}g")
三、Pro Tips
- If exact targets are impossible (e.g., your ingredients can’t hit 220g protein without exceeding fat), the least squares method will give you the closest possible combination.
- Add extra constraints if needed: e.g., total weight limits, maximum servings of a specific ingredient, or budget caps.
- Adjust weights in the loss function to prioritize certain macros—if protein is non-negotiable, multiply its squared error by 2 or 3 to make the optimizer focus more on hitting that target.
内容的提问来源于stack exchange,提问作者Stany Miles

