You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pyomo AbstractModel搭配Python字典改写膳食问题遇错求助

Pyomo抽象模型字典对接膳食规划问题解决方案

修改要点

  • 修正营养字段名称错误:将原合并的Carbo Protein拆分为两个独立字段Carbo、Protein,使营养名称列表长度与营养需求矩阵、食物营养矩阵维度对齐
  • 重构数据字典结构:按照Pyomo抽象模型字典数据规范,拆分集合、参数的赋值逻辑,将嵌套在集合中的参数(成本c、体积V、营养下限Nmin、营养上限Nmax)单独提取为独立的Param字段
  • 修正无效值:将营养上限的None替换为正无穷inf,匹配Param的默认值规则,避免类型报错

可运行完整代码

from __future__ import division

import pyomo.environ as pyo
from pyomo.opt import SolverFactory
from math import inf

food_keys = ['Cheeseburger', 'Ham Sandwich', 'Hamburger', 'Fish Sandwich', 'Chicken Sandwich', 'Fries', 'Sausage Biscuit', 'Lowfat Milk', 'Orange Juice']
cost_vol_keys = ['c', 'V']
cost_vol = [[1.84, 4.0], [2.19, 7.5], [1.84, 3.5], [1.44, 5.0], [2.29, 7.3], [.77, 2.6], [1.29, 4.1], [.60, 8.0], [.72, 12.0]]
F = {food_keys[i]: 
        {cost_vol_keys[j]: 
            cost_vol[i][j] 
            for j in range(len(cost_vol_keys))} 
        for i in range(len(food_keys))}

# 修正营养字段,拆分Carbo和Protein为两个独立字段
nutrition_keys = ['Cal', 'Carbo', 'Protein', 'VitA', 'VitC', 'Calc', 'Iron']
nutrition_req_keys = ['Nmin', 'Nmax']
nutrition_req = [
        [2000, None],
        [ 350,  375],
        [  55, None],
        [ 100, None],
        [ 100, None],
        [ 100, None],
        [ 100, None]
        ]
N = {nutrition_keys[i]: 
        {nutrition_req_keys[j]: 
            nutrition_req[i][j] 
            for j in range(len(nutrition_req_keys))} 
        for i in range(len(nutrition_keys))}

Vmax = 75.0
nutrition = [
    [510, 34, 28, 15,   6, 30, 20],
    [370, 35, 24, 15,  10, 20, 20],
    [500, 42, 25,  6,   2, 25, 20],
    [370, 38, 14,  2,   0, 15, 10],
    [400, 42, 31,  8,  15, 15,  8],
    [220, 26,  3,  0,  15,  0,  2],
    [345, 27, 15,  4,   0, 20, 15],
    [110, 12,  9, 10,   4, 30,  0],
    [ 80, 20,  1,  2, 120,  2,  2]
    ]
a = {(food_keys[i], nutrition_keys[j]): nutrition[i][j] 
        for j in range(len(nutrition_keys)) 
            for i in range(len(food_keys))}

# 拆分参数为Pyomo要求的独立字典格式
c_dict = {f: F[f]['c'] for f in food_keys}
v_dict = {f: F[f]['V'] for f in food_keys}
nmin_dict = {n: N[n]['Nmin'] for n in nutrition_keys}
nmax_dict = {n: N[n]['Nmax'] if N[n]['Nmax'] is not None else inf for n in nutrition_keys}

# 重构符合规范的data字典
data = {None: {
    'F': {None: food_keys}, 
    'N': {None: nutrition_keys}, 
    'c': c_dict,
    'V': v_dict,
    'Nmin': nmin_dict,
    'Nmax': nmax_dict,
    'a': a,
    'Vmax': {None: Vmax},
    }}

model = pyo.AbstractModel()

# 求解器配置:若无Gurobi可替换为cbc/glpk,删除Gurobi专属的opt.options配置即可
solver          = 'gurobi'
solver_io       = 'python'
stream_solver   = False
keepfiles       = False

opt = SolverFactory(solver, solver_io = solver_io)
opt.options['outlev'] = 1
opt.options['solnsens'] = 1
opt.options['bestbound'] = 1

# 模型定义部分无需修改
model.F = pyo.Set()
model.N = pyo.Set()
model.c    = pyo.Param(model.F, within = pyo.PositiveReals)
model.a    = pyo.Param(model.F, model.N, within = pyo.NonNegativeReals)
model.Nmin = pyo.Param(model.N, within = pyo.NonNegativeReals, default = 0.0)
model.Nmax = pyo.Param(model.N, within = pyo.NonNegativeReals, default = inf)
model.V    = pyo.Param(model.F, within = pyo.PositiveReals)
model.Vmax = pyo.Param(within = pyo.PositiveReals)
model.x = pyo.Var(model.F, within = pyo.NonNegativeIntegers)

def cost_rule(model):
    return sum(model.c[i] * model.x[i] for i in model.F)
model.cost = pyo.Objective(rule = cost_rule)

def nutrient_rule(model, j):
    value = sum(model.a[i, j] * model.x[i] for i in model.F)
    return pyo.inequality(model.Nmin[j], value, model.Nmax[j])
model.nutrient_limit = pyo.Constraint(model.N, rule = nutrient_rule)

def volume_rule(model):
    return sum(model.V[i] * model.x[i] for i in model.F) <= model.Vmax
model.volume = pyo.Constraint(rule = volume_rule)

model_instance = model.create_instance(data)
model_instance.pprint()
results = opt.solve(model_instance, keepfiles = keepfiles, tee = stream_solver)

# 输出求解结果
print("\n最优解:")
for f in model_instance.F:
    if pyo.value(model_instance.x[f]) > 1e-6:
        print(f"{f}: {pyo.value(model_instance.x[f])} 份")
print(f"最低总成本:{round(pyo.value(model_instance.cost), 2)} 元")

内容的提问来源于stack exchange,提问作者baxbear

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 19:15:01