名称: python-optimization 描述: Python中数学优化的专家指导 - 系统问题分类、库选择(scipy、pyomo、cvxpy、GEKKO)、求解器配置和实现模式,适用于线性规划、二次规划、非线性规划、混合整数规划、凸优化和全局优化问题 允许工具: [“*”]
Python优化专家
概述
通过系统问题分析、适当的库选择和稳健实现,掌握Python中的数学优化。本技能指导您对优化问题进行分类、选择正确的求解器、实现高效解决方案,并在线性规划、非线性规划、混合整数问题和全局优化中解决收敛问题。
核心价值: 将优化问题从数学公式转化为工作Python代码,使用最适合您特定问题类型的库和求解器。
何时使用
在以下情况下使用本技能:
- 最小化或最大化目标函数
- 参数估计和曲线拟合
- 投资组合优化和资源分配
- 生产计划与调度
- 工程设计优化
- 控制与动态优化
- 解决约束或无约束优化问题
- 在scipy、pyomo、cvxpy或其他优化库之间选择
不要用于:
- 简单求根(使用scipy.optimize.root代替)
- 仅线性代数(使用numpy/scipy.linalg)
- 需要符号数学(使用sympy)
问题分析框架
步骤1:提取问题组件
始终识别:
-
目标函数: 要最小化或最大化什么?
- 示例:最小化成本、最大化利润、最小化误差
-
决策变量: 什么可以改变?
- 连续(实数)还是离散(整数)?
- 有多少变量?
-
约束: 存在什么限制?
- 等式约束:h(x) = 0
- 不等式约束:g(x) ≥ 0
- 边界:下限 ≤ x ≤ 上限
-
数据/参数: 给定了什么值?
- 常数、测量值、输入数据
步骤2:分类问题类型
线性规划(LP)
- 线性目标函数
- 仅线性约束
- 示例:max c’x subject to Ax ≤ b
二次规划(QP)
- 二次目标函数
- 线性约束
- 示例:min (1/2)x’Qx + c’x subject to Ax ≤ b
非线性规划(NLP)
- 非线性目标或约束
- 平滑、可微函数
- 示例:min f(x) subject to g(x) ≥ 0
混合整数规划(MIP/MILP/MINLP)
- 部分或所有变量必须是整数
- 组合优化
- 示例:调度、分配问题
凸优化
- 凸目标函数
- 凸可行域
- 保证全局最优
全局优化
- 怀疑有多个局部最小值
- 非凸问题
- 需要全局搜索策略
最小二乘
- 最小化残差平方和
- 参数估计、曲线拟合
- 专用求解器利用特殊结构
动态优化 / 最优控制
- 时间相关变量
- 微分方程作为约束
- 轨迹优化
步骤3:表征问题规模
小问题: < 100 变量
- 大多数方法效果良好
- scipy.optimize 足够
中等问题: 100-1,000 变量
- 需要高效算法
- 考虑专用求解器
大问题: > 1,000 变量
- 需要稀疏矩阵技术
- 使用pyomo或专用求解器
- 利用问题结构
其他特征:
- 导数可用吗?解析还是数值?
- 平滑还是非平滑?
- 稀疏还是密集?
- 特殊结构(可分离等)?
库选择指南
scipy.optimize - 默认选择
使用时机:
- 小到中等问题(<1,000 变量)
- 无约束或平滑约束非线性规划
- 快速原型和开发
- 最小二乘 / 曲线拟合
- 偏好Python原生解决方案
优势:
- 属于scipy(广泛可用)
- 易于使用,文档良好
- 多种算法可用
- 无需额外依赖
限制:
- 不理想用于大规模问题
- 对混合整数支持有限
- 不如商业求解器复杂
pyomo - 代数建模
使用时机:
- 大规模问题(>1,000 变量)
- 混合整数规划
- 需要多个求解器后端
- 偏好代数建模
- 生产环境
优势:
- 可扩展到非常大的问题
- 支持许多外部求解器
- 清晰的数学表示
- 活跃开发和社区
限制:
- 对许多问题类型需要外部求解器
- 学习曲线较陡
- 额外安装复杂度
cvxpy - 凸优化
使用时机:
- 问题是(或可能是)凸的
- 希望自动凸性验证
- 偏好有纪律的凸规划
- 投资组合优化、控制
优势:
- 自动凸性检测
- 数学表示语法
- 多个求解器后端
- 对凸问题优秀
限制:
- 仅用于凸问题
- 对非凸问题较不灵活
- DCP规则的学习曲线
GEKKO - 动态优化
使用时机:
- 黑盒函数(无导数)
- 动态优化 / 最优控制
- 涉及微分方程
- 过程控制、轨迹优化
优势:
- 自然处理微分方程
- 无导数优化
- 对动态系统良好
- 时间相关问题
限制:
- 专用用例
- 比scipy少见
- 需要GEKKO服务器
比较表
| 库 | 最适合 | 问题类型 | 规模 |
|---|---|---|---|
| scipy.optimize | 通用非线性规划、原型 | 线性规划、二次规划、非线性规划、最小二乘 | 小-中等 |
| pyomo | 大规模、混合整数规划 | 线性规划、混合整数线性规划、非线性规划、混合整数非线性规划 | 任意 |
| cvxpy | 凸问题 | 线性规划、二次规划、二阶锥规划、半定规划 | 中等-大 |
| GEKKO | 动态优化 | 非线性规划、微分代数方程、模型预测控制 | 小-中等 |
scipy.optimize - 方法选择
无约束优化
minimize(f, x0, method='BFGS', jac=gradient)
- 用于: 平滑无约束问题
- 需要: 梯度(或使用有限差分)
- 优点: 快速收敛、稳健
- 缺点: 可能陷入局部最小值
minimize(f, x0, method='L-BFGS-B', bounds=bounds)
- 用于: 大规模带箱约束
- 优点: 内存高效、处理边界
- 缺点: 仅箱约束(无一般约束)
minimize(f, x0, method='Nelder-Mead')
- 用于: 无导数、非平滑
- 优点: 无需导数
- 缺点: 收敛慢、对大规模问题不可靠
minimize(f, x0, method='Powell')
- 用于: 无导数、比Nelder-Mead更好
- 优点: 比Nelder-Mead更稳健
- 缺点: 仍无导数(较慢)
约束优化
minimize(f, x0, method='SLSQP', constraints=cons)
- 用于: 一般约束(等式 + 不等式)
- 优点: 处理所有约束类型
- 缺点: 比trust-constr稳健性差
minimize(f, x0, method='trust-constr', constraints=cons)
- 用于: 困难约束问题
- 优点: 最稳健、可使用Hessian矩阵
- 缺点: 比SLSQP慢
minimize(f, x0, method='COBYLA', constraints=cons)
- 用于: 无导数带约束
- 优点: 无需导数
- 缺点: 慢、精度较低
专用函数
least_squares(residual, x0, bounds=bounds)
- 用于: 非线性最小二乘
- 优点: 利用平方和结构
- 缺点: 仅用于最小二乘问题
curve_fit(model, xdata, ydata, p0=initial)
- 用于: 参数估计、曲线拟合
- 优点: 拟合的简单接口
- 缺点: 仅是least_squares的包装
differential_evolution(f, bounds)
- 用于: 全局优化、多个局部最小值
- 优点: 找到全局最优、无导数
- 缺点: 慢、必须指定边界
linprog(c, A_ub, b_ub)
- 用于: 仅线性规划
- 优点: 专用线性规划、高效
- 缺点: 仅线性问题
实现模式
模式1:无约束优化
from scipy.optimize import minimize
import numpy as np
def objective(x):
"""
要最小化的目标函数。
示例:Rosenbrock函数
f(x) = sum((1 - x[i])^2 + 100*(x[i+1] - x[i]^2)^2)
"""
return sum((1 - x[:-1])**2 + 100*(x[1:] - x[:-1]**2)**2)
def gradient(x):
"""
解析梯度 - 如果可能总是提供!
显著提高收敛速度和可靠性。
"""
grad = np.zeros_like(x)
grad[:-1] = -2*(1 - x[:-1]) - 400*x[:-1]*(x[1:] - x[:-1]**2)
grad[1:] += 200*(x[1:] - x[:-1]**2)
return grad
# 初始猜测
x0 = np.array([0.5, 0.5])
# 优化
result = minimize(objective, x0, method='BFGS', jac=gradient)
# 检查结果
print(f"成功: {result.success}")
print(f"消息: {result.message}")
print(f"最优 x: {result.x}")
print(f"最优值: {result.fun}")
print(f"迭代次数: {result.nit}")
print(f"函数评估次数: {result.nfev}")
模式2:约束优化
from scipy.optimize import minimize
import numpy as np
def objective(x):
"""目标:最小化 x[0]^2 + x[1]^2"""
return x[0]**2 + x[1]**2
def constraint_ineq(x):
"""不等式约束:x[0] + x[1] - 1 >= 0"""
return x[0] + x[1] - 1
def constraint_eq(x):
"""等式约束:x[0]^2 + x[1]^2 - 1 = 0"""
return x[0]**2 + x[1]**2 - 1
# 定义约束(可以有多个)
constraints = [
{'type': 'ineq', 'fun': constraint_ineq}, # g(x) >= 0
{'type': 'eq', 'fun': constraint_eq} # h(x) = 0
]
# 边界:[(下限, 上限), ...],使用None表示无边界
bounds = [(-2, 2), (-2, 2)]
# 初始猜测(如果可能,应该是可行的)
x0 = np.array([0.5, 0.5])
# 优化
result = minimize(
objective,
x0,
method='SLSQP',
constraints=constraints,
bounds=bounds,
options={'ftol': 1e-9, 'maxiter': 1000}
)
print(f"最优 x: {result.x}")
print(f"最优值: {result.fun}")
# 验证约束是否满足
print(f"
约束验证:")
print(f"不等式(应 >= 0): {constraint_ineq(result.x):.6f}")
print(f"等式(应 ~0): {constraint_eq(result.x):.6e}")
模式3:参数估计(曲线拟合)
from scipy.optimize import curve_fit
import numpy as np
def model(x, a, b, c):
"""
模型函数:f(x; 参数)
示例:指数衰减 + 偏移
"""
return a * np.exp(-b * x) + c
# 生成合成数据(实践中,这是您的测量数据)
x_data = np.linspace(0, 10, 50)
y_true = 2.5 * np.exp(-0.3 * x_data) + 0.5
y_data = y_true + 0.1 * np.random.randn(len(x_data)) # 添加噪声
# 将模型拟合到数据
# p0 = 初始参数猜测(可选但推荐)
params, covariance = curve_fit(
model,
x_data,
y_data,
p0=[2, 0.5, 0] # 初始猜测:[a, b, c]
)
# 提取参数和不确定性
a_opt, b_opt, c_opt = params
uncertainties = np.sqrt(np.diag(covariance))
print(f"最优参数:")
print(f" a = {a_opt:.3f} ± {uncertainties[0]:.3f}")
print(f" b = {b_opt:.3f} ± {uncertainties[1]:.3f}")
print(f" c = {c_opt:.3f} ± {uncertainties[2]:.3f}")
# 计算R平方
y_pred = model(x_data, *params)
ss_res = np.sum((y_data - y_pred)**2)
ss_tot = np.sum((y_data - np.mean(y_data))**2)
r_squared = 1 - (ss_res / ss_tot)
print(f"
R² = {r_squared:.4f}")
模式4:最小二乘(残差)
from scipy.optimize import least_squares
import numpy as np
def residuals(params, x, y):
"""
最小二乘的残差函数。
返回:残差数组(模型 - 数据)
"""
a, b, c = params
model = a * np.exp(-b * x) + c
return model - y
# 数据
x_data = np.linspace(0, 10, 50)
y_data = 2.5 * np.exp(-0.3 * x_data) + 0.5 + 0.1*np.random.randn(50)
# 初始猜测
p0 = [2, 0.5, 0]
# 带边界优化
result = least_squares(
residuals,
p0,
args=(x_data, y_data),
bounds=([0, 0, -np.inf], [10, 5, np.inf]) # 下界和上界
)
print(f"成功: {result.success}")
print(f"最优参数: {result.x}")
print(f"最终成本(残差平方和): {result.cost}")
print(f"最优性: {result.optimality}") # 应该小
模式5:线性规划
from scipy.optimize import linprog
import numpy as np
"""
线性规划问题:
最大化: 3*x1 + 2*x2
约束: x1 + x2 <= 4
2*x1 + x2 <= 5
x1, x2 >= 0
注意:linprog最小化,所以对于最大化需取负目标函数
"""
# 目标系数(对于最大化取负)
c = [-3, -2]
# 不等式约束:A_ub @ x <= b_ub
A_ub = np.array([
[1, 1], # x1 + x2 <= 4
[2, 1] # 2*x1 + x2 <= 5
])
b_ub = np.array([4, 5])
# 边界:x1, x2 >= 0
bounds = [(0, None), (0, None)]
# 求解
result = linprog(
c,
A_ub=A_ub,
b_ub=b_ub,
bounds=bounds,
method='highs' # 默认,最有效
)
print(f"成功: {result.success}")
print(f"最优 x: {result.x}")
print(f"最优值(最小化): {result.fun}")
print(f"最优值(最大化): {-result.fun}")
模式6:全局优化
from scipy.optimize import differential_evolution
import numpy as np
def objective(x):
"""
具有多个局部最小值的函数。
示例:Rastrigin函数
"""
A = 10
return A*len(x) + sum(x**2 - A*np.cos(2*np.pi*x))
# 必须为每个变量指定边界
bounds = [(-5.12, 5.12), (-5.12, 5.12)]
# 全局优化
result = differential_evolution(
objective,
bounds,
strategy='best1bin',
maxiter=1000,
popsize=15,
tol=1e-7,
atol=1e-9,
workers=-1, # 使用所有CPU核心
polish=True, # 最后局部细化
seed=42 # 为可重复性
)
print(f"成功: {result.success}")
print(f"全局最小值 x: {result.x}")
print(f"全局最小值: {result.fun}")
print(f"函数评估次数: {result.nfev}")
# 对比,尝试从随机起点局部优化
from scipy.optimize import minimize
x0 = np.random.uniform(-5.12, 5.12, 2)
local_result = minimize(objective, x0, method='BFGS')
print(f"
从随机起点局部优化:")
print(f"局部最小值: {local_result.fun}")
print(f"(全局更好: {result.fun < local_result.fun})")
模式7:pyomo(大规模 / 混合整数)
import pyomo.environ as pyo
# 创建模型
model = pyo.ConcreteModel()
# 决策变量
model.x = pyo.Var(domain=pyo.NonNegativeReals)
model.y = pyo.Var(domain=pyo.Integers, bounds=(0, 10))
model.z = pyo.Var([1, 2, 3], domain=pyo.Binary) # 索引二进制变量
# 参数(可选)
model.a = pyo.Param(initialize=2.5)
model.b = pyo.Param([1, 2, 3], initialize={1: 1.0, 2: 2.0, 3: 3.0})
# 目标函数
model.obj = pyo.Objective(
expr=model.x**2 + model.y + sum(model.z[i] for i in [1,2,3]),
sense=pyo.minimize # 或 pyo.maximize
)
# 约束
model.con1 = pyo.Constraint(expr=model.x + model.y >= 5)
model.con2 = pyo.Constraint(expr=2*model.x - model.y <= 10)
model.con3 = pyo.Constraint(expr=sum(model.z[i] for i in [1,2,3]) <= 2)
# 求解
# 对于连续:'ipopt'(非线性)或'glpk'(线性)
# 对于整数:'cbc', 'glpk', 'gurobi'(商业)
solver = pyo.SolverFactory('ipopt')
results = solver.solve(model, tee=True) # tee=True显示求解器输出
# 检查是否最优
if results.solver.termination_condition == pyo.TerminationCondition.optimal:
print("
找到最优解!")
print(f"x = {pyo.value(model.x):.4f}")
print(f"y = {pyo.value(model.y):.4f}")
print(f"z = {[pyo.value(model.z[i]) for i in [1,2,3]]}")
print(f"目标值 = {pyo.value(model.obj):.4f}")
else:
print(f"求解器状态: {results.solver.termination_condition}")
模式8:cvxpy(凸优化)
import cvxpy as cp
import numpy as np
"""
投资组合优化示例:
在最小预期回报约束下最小化方差
"""
# 问题数据
n = 4 # 资产数量
mu = np.array([0.12, 0.10, 0.07, 0.03]) # 预期回报
Sigma = np.array([ # 协方差矩阵
[0.10, 0.03, 0.01, 0.00],
[0.03, 0.08, 0.02, 0.01],
[0.01, 0.02, 0.05, 0.01],
[0.00, 0.01, 0.01, 0.02]
])
# 变量
w = cp.Variable(n) # 投资组合权重
# 目标:最小化方差
objective = cp.Minimize(cp.quad_form(w, Sigma))
# 约束
constraints = [
cp.sum(w) == 1, # 权重和为1
w >= 0, # 无卖空
mu @ w >= 0.10 # 最小预期回报
]
# 求解
problem = cp.Problem(objective, constraints)
problem.solve()
# 结果
print(f"状态: {problem.status}")
if problem.status == 'optimal':
print(f"最优投资组合权重: {w.value}")
print(f"投资组合方差: {problem.value:.6f}")
print(f"投资组合标准差: {np.sqrt(problem.value):.4f}")
print(f"预期回报: {(mu @ w.value):.4f}")
else:
print(f"问题无法求解: {problem.status}")
最佳实践
1. 总是提供解析梯度
原因: 10-100倍更快收敛,更可靠
def objective(x):
return x[0]**2 + x[1]**2
def gradient(x):
"""解析梯度 - 比有限差分好得多"""
return np.array([2*x[0], 2*x[1]])
# 好:使用解析梯度
result = minimize(objective, x0, method='BFGS', jac=gradient)
# 可以但较慢:使用有限差分
result = minimize(objective, x0, method='BFGS')
2. 验证梯度
from scipy.optimize import check_grad
# 检查梯度准确性
error = check_grad(objective, gradient, x0)
print(f"梯度误差: {error}") # 应 < 1e-5
# 对于约束
for con in constraints:
if 'jac' in con:
error = check_grad(con['fun'], con['jac'], x0)
print(f"约束梯度误差: {error}")
3. 缩放变量
问题: 变量量级差异很大
# 坏:x1 ~ 1e-6, x2 ~ 1e6
x = [1e-6, 1e6]
解决方案: 归一化到相似尺度
# 好:两个变量 ~ O(1)
x_scaled = [x[0] * 1e6, x[1] / 1e6]
def objective_scaled(x_scaled):
x = [x_scaled[0] / 1e6, x_scaled[1] * 1e6] # 转换回
return original_objective(x)
4. 提供良好的初始猜测
# 坏:随机或任意起点
x0 = np.zeros(n)
# 好:物理合理或可行起点
x0 = np.array([1.0, 2.0, 0.5]) # 基于问题知识
# 更好:对于非凸问题尝试多个起点
initial_guesses = [
np.array([1.0, 2.0]),
np.array([-1.0, -2.0]),
np.random.randn(2)
]
results = [minimize(objective, x0) for x0 in initial_guesses]
best_result = min(results, key=lambda r: r.fun)
5. 验证解决方案
def validate_solution(result, constraints, bounds):
"""综合解决方案验证"""
# 检查优化成功
assert result.success, f"优化失败: {result.message}"
# 检查不等式约束:g(x) >= 0
for i, con in enumerate([c for c in constraints if c['type'] == 'ineq']):
val = con['fun'](result.x)
assert val >= -1e-6, f"不等式约束 {i} 违反: {val:.2e}"
# 检查等式约束:h(x) = 0
for i, con in enumerate([c for c in constraints if c['type'] == 'eq']):
val = con['fun'](result.x)
assert abs(val) < 1e-6, f"等式约束 {i} 违反: {val:.2e}"
# 检查边界
if bounds is not None:
for i, (lb, ub) in enumerate(bounds):
if lb is not None:
assert result.x[i] >= lb - 1e-6, f"下界 {i} 违反"
if ub is not None:
assert result.x[i] <= ub + 1e-6, f"上界 {i} 违反"
print("✓ 所有约束满足")
return True
# 使用它
validate_solution(result, constraints, bounds)
6. 处理收敛问题
常见问题和解决方案:
# 问题:"未达到预期误差"
# 解决方案1:放宽容差
result = minimize(
objective, x0,
method='BFGS',
options={'ftol': 1e-6, 'gtol': 1e-5} # 较宽松
)
# 解决方案2:缩放变量
x_scaled = x / typical_scale
result = minimize(objective_scaled, x_scaled)
# 解决方案3:尝试不同方法
result = minimize(objective, x0, method='trust-constr')
# 解决方案4:更好的初始猜测
x0 = feasible_starting_point()
# 问题:陷入局部最小值
# 解决方案:全局优化
result = differential_evolution(objective, bounds)
# 问题:约束不兼容
# 解决方案:检查约束可行性
from scipy.optimize import fsolve
# 尝试找到任何可行点
def feasibility(x):
violations = []
for con in constraints:
if con['type'] == 'eq':
violations.append(con['fun'](x))
return violations
x_feasible = fsolve(feasibility, x0)
常见问题类型 - 快速参考
1. 无约束:最小化 f(x)
minimize(f, x0, method='BFGS', jac=grad)
2. 箱约束:最小化 f(x) 约束 lb ≤ x ≤ ub
minimize(f, x0, method='L-BFGS-B', bounds=bounds)
3. 一般约束:最小化 f(x) 约束 g(x) ≥ 0, h(x) = 0
cons = [{'type': 'ineq', 'fun': g}, {'type': 'eq', 'fun': h}]
minimize(f, x0, method='SLSQP', constraints=cons)
4. 最小二乘:最小化 ||r(x)||²
least_squares(residual, x0, bounds=(lb, ub))
5. 曲线拟合:将模型拟合到数据
params, cov = curve_fit(model, xdata, ydata, p0=initial)
6. 线性规划:最小化 c’x 约束 Ax ≤ b
linprog(c, A_ub=A, b_ub=b, bounds=bounds)
7. 混合整数:某些变量必须是整数
# 使用 pyomo
model.x = pyo.Var(domain=pyo.Integers)
solver = pyo.SolverFactory('cbc')
solver.solve(model)
8. 全局:多个局部最小值
differential_evolution(f, bounds)
9. 投资组合优化
# cvxpy
w = cp.Variable(n)
objective = cp.Minimize(cp.quad_form(w, Sigma))
constraints = [cp.sum(w) == 1, w >= 0, mu @ w >= target_return]
problem = cp.Problem(objective, constraints)
problem.solve()
10. 带不确定性的参数估计
params, cov = curve_fit(model, xdata, ydata)
uncertainties = np.sqrt(np.diag(cov))
响应格式
当解决优化问题时,总是:
1. 重述问题
"根据您的描述,这是一个 [问题类型] 问题:
目标: 最小化/最大化 f(x) = … 变量: x ∈ R^n(或对于整数,x ∈ Z^n) 约束:
- [列出不等式约束]
- [列出等式约束]
- [列出边界]"
2. 解释库/方法选择
"由于此问题具有 [特征],我推荐 [库] 与 [方法]:
- [原因1]
- [原因2]
- [如果这不奏效,替代方案]"
3. 提供完整实现
# 完整、可运行代码,带注释
# 包含导入、数据、函数、优化、验证
4. 显示和解释结果
"结果:
- 最优 x:[值]
- 最优值:[值]
- 约束满足:✓ / ✗
- 收敛:[迭代次数,函数评估次数]
解释: [解决方案在上下文中的含义]"
5. 如果需要,建议改进
"如果出现收敛问题:
- 尝试 [替代方法]
- 调整 [参数]
- 考虑 [问题重构]"
高级主题
多目标优化
对于具有 多个冲突目标 的问题(最小化成本 AND 最大化性能),使用专用的 python-multiobjective-optimization 技能,涵盖:
- Pareto最优性和Pareto前沿
- 进化算法(NSGA-II, NSGA-III, MOEA/D)
- 标量化方法(加权和,ε-约束)
- 库:pymoo, platypus, DEAP
- Pareto分析和决策制定
- 可视化技术
快速示例 - 使用scipy的加权和标量化:
from scipy.optimize import minimize
def scalarize_objectives(x, weights):
"""多目标的加权和方法"""
f1 = objective1(x)
f2 = objective2(x)
return weights[0] * f1 + weights[1] * f2
# 求解不同权重组合以追踪Pareto前沿
weights_list = [(1, 0), (0.75, 0.25), (0.5, 0.5), (0.25, 0.75), (0, 1)]
pareto_front = []
for weights in weights_list:
result = minimize(
lambda x: scalarize_objectives(x, weights),
x0,
method='SLSQP',
constraints=constraints
)
if result.success:
pareto_front.append({
'x': result.x,
'f1': objective1(result.x),
'f2': objective2(result.x)
})
注意: 加权和仅找到Pareto前沿的凸部分。对于全面多目标优化,见python-multiobjective-optimization技能。
鲁棒优化
def worst_case_objective(x, uncertainty_scenarios):
"""最小化最坏情况性能"""
return max(objective(x, scenario) for scenario in uncertainty_scenarios)
result = minimize(worst_case_objective, x0, args=(scenarios,))
随机优化
def expected_objective(x, n_samples=1000):
"""最小化随机参数上的期望值"""
samples = np.random.normal(mu, sigma, (n_samples, n_params))
return np.mean([objective(x, sample) for sample in samples])
result = minimize(expected_objective, x0)
故障排除指南
| 问题 | 症状 | 解决方案 |
|---|---|---|
| 收敛慢 | 许多迭代,进展慢 | 提供解析梯度,缩放变量,更好的x0 |
| 局部最小值 | 不同x0给出不同解 | 使用differential_evolution,尝试多个起点 |
| 约束违反 | 解不满足约束 | 检查约束公式,确保可行x0,收紧容差 |
| “未达到预期误差” | 结果中警告 | 放宽容差,缩放变量,尝试不同方法 |
| 数值误差 | NaN或Inf值 | 缩放变量,避免目标中的极端值 |
| 内存错误 | 大问题崩溃 | 使用稀疏矩阵,L-BFGS-B,或带稀疏求解器的pyomo |
安装
# 核心优化
pip install scipy
# 对于大规模和混合整数
pip install pyomo
# 为pyomo安装求解器
conda install -c conda-forge ipopt # 非线性
conda install -c conda-forge glpk # 线性/整数
pip install cplex # 商业,需要许可证
# 对于凸优化
pip install cvxpy
# 对于动态优化
pip install gekko
额外资源
- SciPy优化教程: https://docs.scipy.org/doc/scipy/tutorial/optimize.html
- Pyomo文档: https://pyomo.readthedocs.io/
- CVXPY教程: https://www.cvxpy.org/tutorial/
- 凸优化(Boyd & Vandenberghe): https://web.stanford.edu/~boyd/cvxbook/
- 数值优化(Nocedal & Wright): 经典教科书
相关技能
python-multiobjective-optimization- 带Pareto前沿的多目标优化(NSGA-II, NSGA-III, pymoo)pycse- 带置信区间的回归分析,常微分方程求解python-best-practices- 优化代码的代码质量和测试python-ase- 材料科学中的原子结构优化