49 lines
2.3 KiB
Python
49 lines
2.3 KiB
Python
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
|
||
|