Files
feed-formula-calculator/optimize_feed.py
2025-09-23 00:53:10 +08:00

49 lines
2.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import pulp
def optimize_feed(requirements, ingredients, result_fields, optimization_type='min'):
"""
优化饲料配方,计算最低/最高目标值的原料比例
:param requirements: 猪营养需求字典,如 {'蛋白_下限': 16, '能量_下限': 12, '纤维_上限': 8}
:param ingredients: 原料数据字典,如 {'构树叶': {'蛋白': 18, '能量': 10, '纤维': 5, '价格': 500}}
:param result_fields: 结果字段列表,如 ['比例', '成本']
:param optimization_type: 'min'(最小化,如成本)或 'max'(最大化,如消化率)
:return: 字典,含结果字段和值,如 {'构树叶': {'比例': 0.2, '成本': 100}, '总成本': 1475}
"""
# 创建模型
sense = pulp.LpMinimize if optimization_type == 'min' else pulp.LpMaximize
model = pulp.LpProblem("Feed_Optimization", sense)
# 决策变量原料比例0-1
x = pulp.LpVariable.dicts("比例", ingredients, lowBound=0, upBound=1)
# 目标函数:优化指定字段(如价格)
target_field = next(f for f in ingredients[list(ingredients.keys())[0]] if '价格' in f or '成本' in f) # 默认优化价格
model += pulp.lpSum([x[i] * ingredients[i][target_field] for i in ingredients]), "目标"
# 约束1总比例=100%
model += pulp.lpSum([x[i] for i in ingredients]) == 1, "总比例"
# 约束2营养需求下限/上限)
for req, value in requirements.items():
if '下限' in req:
nutrient = req.replace('_下限', '')
model += pulp.lpSum([x[i] * ingredients[i][nutrient] for i in ingredients]) >= value, req
elif '上限' in req:
nutrient = req.replace('_上限', '')
model += pulp.lpSum([x[i] * ingredients[i][nutrient] for i in ingredients]) <= value, req
# 求解
model.solve()
# 构建结果
if pulp.LpStatus[model.status] != 'Optimal':
return {"错误": "无解!检查原料数据或需求(比如纤维全超上限?)"}
result = {}
total_target = pulp.value(model.objective)
result['' + target_field] = round(total_target, 2)
for i in ingredients:
result[i] = {field: round(pulp.value(x[i]) * 100, 2) if field == '比例' else round(
pulp.value(x[i]) * ingredients[i][target_field], 2) for field in result_fields}
return result