python - 使用混合浓度作为线性优化的约束
问题描述
我有下表,必须从中创建一个具有特定蛋白质和碳水化合物价值的食谱。
并使用 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]]
目标函数,其中上限“数据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])
最后是求解器:
状态 = 求解器.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]]
Tjis way 我会多吃 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
如何将此约束添加到求解器?
解决方案
(f1*W + f2*X + f3*Y + f4*Z)/(W+X+Y+Z) = 10
是相同的
f1*W + f2*X + f3*Y + f4*Z = 10*(W+X+Y+Z)
这现在是线性的。
而且,如果我们错过了一些数学课,我们可以把它写成标准的 LP 约束:
(f1-10)*W + (f2-10)*X + (f3-10)*Y + (f4-10)*Z = 0
推荐阅读
- go - 为什么在打印结构字段时不调用我的类型的 String() 方法?
- reactjs - react js中的eventbrite入门
- javascript - 通过 splash 评估 javascript 时如何避免 CSP 错误?
- logging - 具有 ILoggerFactory 和 Autofac 注入服务的自定义 Serilog 丰富器
- python - Python 缩进辅助
- kubernetes-helm - 在 HELM 模板定义函数中使用变量
- firebase - 在多个屏幕中调用相同的 onAuthStateChanged 监听器会创建新的监听器?
- listview - SwipeView 仅在执行滑动后对某些行做出响应!(直到页面手动导航)
- html - 从 jQuery 和 Thymeleaf 中的输入计算值?
- snowflake-cloud-data-platform - 带有更改日志的雪花建模,仅包含新记录和已删除记录