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

Pyomo非线性优化:设置输入标准差为优化目标的报错问题

问题原因

你的判断是对的,报错来自两处硬伤:

  1. Python标准库的statistics.stdev只接收已赋值的数值类型输入,无法解析Pyomo的决策变量对象。Pyomo建模时需要用框架原生支持的运算逻辑构建目标/约束表达式,不能直接调用Python原生的数值计算函数处理未赋值的变量对象,否则就会触发你看到的类型转换错误。
  2. 你选用的glpk是纯线性规划求解器,本身不支持非线性/二次目标,就算表达式写对了也无法求解。
修复方案

核心逻辑

最小化标准差和最小化方差是完全等价的优化问题(标准差是方差的严格单调递增函数),你可以直接用方差作为目标,省去开平方的计算,降低问题非线性程度。
方差的数学定义是所有变量与均值差的平方的平均值,你可以直接用Pyomo支持的加减乘除、幂运算手动写出这个表达式,不需要调用外部统计库。
同时把求解器更换为支持非线性规划的开源求解器ipopt即可。

修正后的可运行代码

import pyomo.environ as pyo

model = pyo.ConcreteModel()

# 定义决策变量
model.x1 = pyo.Var(domain=pyo.NonNegativeReals)
model.x2 = pyo.Var(domain=pyo.NonNegativeReals)
model.x3 = pyo.Var(domain=pyo.NonNegativeReals)
model.x4 = pyo.Var(domain=pyo.NonNegativeReals)

# 计算变量均值
x_vars = [model.x1, model.x2, model.x3, model.x4]
var_count = len(x_vars)
x_mean = sum(x_vars) / var_count

# 手动构建方差目标
model.min_variance = pyo.Objective(
    expr = sum((x - x_mean)**2 for x in x_vars) / var_count,
    sense = pyo.minimize
)

# 定义约束
model.total_load = pyo.Constraint(expr = model.x1 + model.x2 + model.x3 + model.x4 >= 500)
model.x1_cap = pyo.Constraint(expr = model.x1 <= 300)
model.x2_cap = pyo.Constraint(expr = model.x2 <= 200)
model.x3_cap = pyo.Constraint(expr = model.x3 <= 100)
model.x4_cap = pyo.Constraint(expr = model.x4 <= 200)

# 调用ipopt求解,需提前安装ipopt
solver = pyo.SolverFactory('ipopt')
solve_result = solver.solve(model)
solve_result.write()

# 输出结果
print("最小方差值:", model.min_variance())
print(f"各变量取值:x1={model.x1()}, x2={model.x2()}, x3={model.x3()}, x4={model.x4()}")

补充说明

  • 如果你必须输出标准差作为结果,只需要在求解完成后对方差值开平方即可,不需要把标准差写到目标里增加求解复杂度。如果一定要把标准差作为目标,把目标表达式替换为pyo.sqrt(sum((x - x_mean)**2 for x in x_vars) / var_count)即可,ipopt原生支持平方根运算。
  • 安装ipopt如果用conda环境,直接执行conda install -c conda-forge ipopt即可完成安装。
  • 这个问题的目标是凸二次函数,约束全为线性,属于标准二次规划问题,你也可以把方差展开为标准二次型后调用支持QP的求解器,求解速度会比通用非线性求解器更快。

内容的提问来源于stack exchange,提问作者A.Shoman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 04:48:31