如何在Pyomo中不初始化变量,让求解器自行计算初始点?
问题描述
默认情况下Pyomo会自动初始化变量,求解器会基于这个初始点进行计算。有没有办法不让Pyomo初始化变量,转而让求解器自行生成初始点?我试过把变量初始化为None,但还是有初始点被传递给求解器。
以下是测试示例:
import pyomo.environ as pyo model = pyo.ConcreteModel() model.x = pyo.Var(within=pyo.Reals) model.objective = pyo.Objective( expr=(model.x + 10)**2, sense=pyo.minimize) solver = pyo.SolverFactory('knitroampl') results = solver.solve(model, tee=True)
按预期,若未提供初始点Knitro应提示"No initial point provided",但实际运行输出如下:
Knitro presolve eliminated 0 variables and 0 constraints. concurrent_evals 0 datacheck 0 hessian_no_f 1 hessopt 1 The problem is identified as unconstrained. Problem Characteristics ( Presolved) ----------------------- Objective goal: Minimize Objective type: quadratic Number of variables: 1 ( 1) bounded below only: 0 ( 0) bounded above only: 0 ( 0) bounded below and above: 0 ( 0) fixed: 0 ( 0) free: 1 ( 1) Number of constraints: 0 ( 0) linear equalities: 0 ( 0) quadratic equalities: 0 ( 0) gen. nonlinear equalities: 0 ( 0) linear one-sided inequalities: 0 ( 0) quadratic one-sided inequalities: 0 ( 0) gen. nonlinear one-sided inequalities: 0 ( 0) linear two-sided inequalities: 0 ( 0) quadratic two-sided inequalities: 0 ( 0) gen. nonlinear two-sided inequalities: 0 ( 0) Number of nonzeros in Jacobian: 0 ( 0) Number of nonzeros in Hessian: 1 ( 1) Knitro using the Interior-Point/Barrier Direct algorithm. Iter Objective FeasError OptError ||Step|| CGits -------- -------------- ---------- ---------- ---------- ------- 0 1.000000e+02 0.000e+00 1 0.000000e+00 0.000e+00 0.000e+00 1.000e+01 0 EXIT: Locally optimal solution found. Final Statistics ---------------- Final objective value = 0.00000000000000e+00 Final feasibility error (abs / rel) = 0.00e+00 / 0.00e+00 Final optimality error (abs / rel) = 0.00e+00 / 0.00e+00 # of iterations = 1 # of CG iterations = 0 # of function evaluations = 0 # of gradient evaluations = 0 # of Hessian evaluations = 0 Total program time (secs) = 0.00318 ( 0.016 CPU time) Time spent in evaluations (secs) = 0.00000 ===============================================================================
解决方法
Pyomo默认会给未显式初始化的变量赋值0作为初始值(从迭代0的目标值100可反推,x初始值为0)。要让求解器自行生成初始点,可通过以下方式实现:
- 设置Knitro专属选项
直接通过求解器选项告知Knitro不使用Pyomo提供的初始点,或启用其自动初始点生成功能:
solver = pyo.SolverFactory('knitroampl') # 禁止使用Pyomo传递的初始点 solver.options['initial_point'] = None # 或开启Knitro自动初始点生成(参数值参考Knitro官方文档) solver.options['initpoint'] = 2 results = solver.solve(model, tee=True)
- 清空变量初始值并禁用热启动
先将变量的value设为None,再配合warmstart=False参数避免传递初始值:
model.x.value = None results = solver.solve(model, tee=True, warmstart=False)
- 通过AMPL接口传递缺失值
由于使用的是knitroampl(基于AMPL接口),可将变量初始值设为AMPL识别的缺失值,让Knitro知晓无初始点:
model.x = pyo.Var(within=pyo.Reals, initialize=pyo.Param(initialize=None))
若设置正确,Knitro会输出"No initial point provided",并使用自身逻辑生成初始点开始计算。
内容的提问来源于Stack Exchange,提问作者fontanf
相关产品推荐
相关产品推荐

