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

Pyomo调用CBC求解器仅迭代一次未寻优的问题求助

问题

使用Pyomo进行最小化寻优时,求解器仅执行一次迭代就停止,未尝试寻找极小值点。

问题代码

import pyomo.environ as pyo
model = pyo.ConcreteModel()
model.x = pyo.Var([0, 1], domain = pyo.NonNegativeIntegers, initialize = [10, 3])
def loss(args):
    a, b = args[0].value, args[1].value
    return (a - 30) ** 2 + (b - 5) ** 2
model.obj = pyo.Objective(expr = loss((model.x[0], model.x[1])), sense = pyo.minimize)
model.c1 = pyo.Constraint(expr = model.obj >= 0.0)
solver_options = pyo.SolverFactory("cbc").options
solver_options["max_iter"] = 10
solver_options["tolerance"] = 0.000001
solver_options["max_seconds"] = 10
results = pyo.SolverFactory("cbc").solve(model, options = solver_options)
results.write()

求解输出

# ==========================================================
# = Solver Results                                         =
# ==========================================================
# ----------------------------------------------------------
#   Problem Information
# ----------------------------------------------------------
Problem: 
- Name: unknown
  Lower bound: 404.0
  Upper bound: 404.0
  Number of objectives: 1
  Number of constraints: 2
  Number of variables: 1
  Number of nonzeros: 0
  Sense: minimize
# ----------------------------------------------------------
#   Solver Information
# ----------------------------------------------------------
Solver: 
- Status: ok
  User time: -1.0
  System time: 0.0
  Wallclock time: 0.0
  Termination condition: optimal
  Termination message: Model was solved to optimality (subject to tolerances), and an optimal solution is available.
  Statistics: 
    Branch and bound: 
      Number of bounded subproblems: None
      Number of created subproblems: None
    Black box: 
      Number of iterations: 0
  Error rc: 0
  Time: 0.008995532989501953
# ----------------------------------------------------------
#   Solution Information
# ----------------------------------------------------------
Solution: 
- number of solutions: 0
  number of solutions displayed: 0

核心原因

代码的致命问题是:定义目标函数时直接调用了loss()函数并获取变量的当前值。这会让Pyomo将目标函数固定为初始化变量时计算出的常量(这里是(10-30)² + (3-5)² = 404),而非构建与model.x变量关联的动态表达式。

从求解器输出也能验证:问题信息里显示Number of variables: 1(实际应为2个变量),目标函数是常量,所以求解器直接判定已达最优,停止计算。

解决方案

根据场景分为两种处理方式:

场景1:函数可转化为Pyomo表达式(示例场景)

如果损失函数能用Pyomo变量表达式表示,直接在Objective中定义关联表达式,不要调用.value获取变量当前值:

import pyomo.environ as pyo
model = pyo.ConcreteModel()
model.x = pyo.Var([0, 1], domain=pyo.NonNegativeIntegers, initialize=[10, 3])

# 用Pyomo变量构建目标函数表达式
def loss_expr(model):
    return (model.x[0] - 30)**2 + (model.x[1] - 5)**2

model.obj = pyo.Objective(rule=loss_expr, sense=pyo.minimize)
model.c1 = pyo.Constraint(expr=model.obj >= 0.0)

solver = pyo.SolverFactory("cbc")
solver.options["max_iter"] = 10
solver.options["tolerance"] = 1e-6
solver.options["max_seconds"] = 10
results = solver.solve(model)
results.write()

# 查看最优解
print(f"最优x0: {pyo.value(model.x[0])}, 最优x1: {pyo.value(model.x[1])}")

这种方式下,Pyomo能正确识别变量与目标函数的依赖关系,求解器会正常迭代寻优。

场景2:使用依赖外部包的复杂黑箱函数

如果损失函数依赖外部库、无法转化为Pyomo表达式,需要使用支持黑箱优化的求解器,或通过Pyomo的ExternalFunction包装函数。

方法:用ExternalFunction包装黑箱函数

import pyomo.environ as pyo
from pyomo.core.expr.external import ExternalFunction

model = pyo.ConcreteModel()
model.x = pyo.Var([0, 1], domain=pyo.NonNegativeIntegers, initialize=[10, 3])

# 模拟依赖外部包的复杂黑箱函数
def black_box_loss(a, b):
    # 替换为你的实际复杂逻辑
    return (a - 30)**2 + (b - 5)**2

# 注册外部函数
model.loss_fn = ExternalFunction(black_box_loss)

# 用外部函数定义目标函数
model.obj = pyo.Objective(expr=model.loss_fn(model.x[0], model.x[1]), sense=pyo.minimize)
model.c1 = pyo.Constraint(expr=model.obj >= 0.0)

# 使用支持黑箱优化的求解器,比如bonmin(支持混合整数黑箱优化)
solver = pyo.SolverFactory("bonmin")
solver.options["max_iter"] = 100
results = solver.solve(model)
results.write()

print(f"最优x0: {pyo.value(model.x[0])}, 最优x1: {pyo.value(model.x[1])}")

注意事项

  • CBC是线性/整数规划求解器,不支持黑箱优化,需更换为ipopt(连续变量)或bonmin(混合整数变量)这类求解器。
  • 确保已安装对应的求解器(可通过conda install -c conda-forge ipopt bonmin安装)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:03:23