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

Pyomo调用MindtPy求解时报NoneType无__round__方法错误如何解决

Pyomo调用MindtPy求解MINLP时报TypeError: type NoneType doesn't define round method 问题分析

问题复现

用户使用Pyomo实现带二元变量的动态优化问题,代码如下:

import pyomo
import pyomo.opt
import pyomo.environ as pe
import numpy as np

a = np.array([1,1,1,15])
b = np.array([1,2,3,4])
c = 10
P_res = 5

model = pe.ConcreteModel(name = "base optimizer")

model.M = pe.RangeSet(1,2)
model.T = pe.RangeSet(1,P_res)
model.state = pe.RangeSet(1,4)

st_lb = np.array((-1.22,) * P_res)
st_ub = np.array((1.22,) * P_res)
th_lb = np.array((0,) * P_res)
th_ub = np.array((1.0,) * P_res)

def th_b(model, i):
    return (th_lb[i-1], th_ub[i-1])
model.th = pe.Var(model.T, domain=pe.Reals, bounds = th_b)
model.x = pe.Var(model.T, model.state, domain = pe.Reals)
model.z_predicate = pe.Var(model.T, model.M, domain=pe.Binary)

def obj_rule(model):
    return model.th[P_res]**2
model.OBJ = pe.Objective(rule=obj_rule, sense = pe.minimize)

def init_state(model,s):
    return model.x[1,s]  == a[s-1]
def dynamic_1(model,t):
    if t == P_res:
        return pe.Constraint.Skip
    return model.x[t+1,1] == model.x[t,1] + model.x[t,4] * pe.cos(model.x[t,3])
def dynamic_2(model,t):
    if t == P_res:
        return pe.Constraint.Skip
    return model.x[t+1,2] == model.x[t,2] + model.x[t,4] * pe.sin(model.x[t,3])
def dynamic_3(model,t):
    if t == P_res:
        return pe.Constraint.Skip
    return model.x[t+1,4] == model.x[t,4] + model.th[t]
    
model.InitConstraint = pe.Constraint(model.state, rule = init_state)
model.DynConstraint1 = pe.Constraint(model.T, rule=dynamic_1) 
model.DynConstraint2 = pe.Constraint(model.T, rule=dynamic_2)
model.DynConstraint3 = pe.Constraint(model.T, rule=dynamic_3)

def binary_constraint(model,t):
    return  model.z_predicate[t,1] <= 1 
model.BiConstraint = pe.Constraint(model.T,rule=binary_constraint)
 
solver = pyomo.opt.SolverFactory('mindtpy')
results = solver.solve(model, mip_solver='gurobi', nlp_solver='ipopt', tee=True)

运行后报错栈如下:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-d441aab4faca> in <module>
     56 
     57 solver = pyomo.opt.SolverFactory('mindtpy')
---> 58 results = solver.solve(model, mip_solver='gurobi', nlp_solver='ipopt', tee=True)
     59 
     60 # solver = pyomo.opt.SolverFactory('ipopt')

c:\users\hongk\appdata\local\programs\python\python36\lib\site-packages\pyomo\contrib\mindtpy\MindtPy.py in solve(self, model, **kwds)
    169             # Algorithm main loop
    170             with time_code(solve_data.timing, 'main loop'):
--> 171                 MindtPy_iteration_loop(solve_data, config)
    172             if solve_data.best_solution_found is not None:
    173                 # Update values in original model

c:\users\hongk\appdata\local\programs\python\python36\lib\site-packages\pyomo\contrib\mindtpy\iterate.py in MindtPy_iteration_loop(solve_data, config)
     99                     fixed_nlp, fixed_nlp_result, solve_data, config)
    100 
--> 101         if algorithm_should_terminate(solve_data, config, check_cycling=True):
    102             last_iter_cuts = False
    103             break

c:\users\hongk\appdata\local\programs\python\python36\lib\site-packages\pyomo\contrib\mindtpy\iterate.py in algorithm_should_terminate(solve_data, config, check_cycling)
    307     if check_cycling:
    308         if config.cycling_check or config.use_tabu_list:
--> 309             solve_data.curr_int_sol = get_integer_solution(solve_data.mip)
    310             if config.cycling_check and solve_data.mip_iter >= 1:
    311                 if solve_data.curr_int_sol in set(solve_data.integer_list):

c:\users\hongk\appdata\local\programs\python\python36\lib\site-packages\pyomo\contrib\mindtpy\util.py in get_integer_solution(model, string_zero)
    550                     temp.append(int(round(var.value)))
    551             else:
--> 552                 temp.append(int(round(var.value)))
    553     return tuple(temp)
    554 

TypeError: type NoneType doesn't define __round__ method

用户测试发现:注释掉model.BiConstraint并将求解器替换为Ipopt后,程序可正常运行,推测报错与该约束有关。

报错诱因

1. 存在完全冗余的二元变量

你定义的model.z_predicate是维度为T×M(M=1、2)的二元变量,存在两个问题:

  • 你仅对z_predicate[t,1]添加了<=1的约束,而二元变量的默认上界就是1,该约束完全无效
  • z_predicate[t,2]从未出现在任何约束、目标函数中,属于对优化结果无任何影响的自由变量
  • 整个z_predicate变量族都没有参与目标函数计算,不会对优化结果产生任何影响

2. MindtPy的整数解提取逻辑触发报错

MindtPy求解MINLP问题时,会先调用Gurobi求解MIP子问题。对于这类对目标、约束无影响的冗余二元变量,Gurobi不会为其分配具体值(无论取0还是1都不影响结果,求解器会直接跳过赋值),导致变量的value属性为None。当MindtPy执行整数解提取逻辑时,尝试对None调用round()方法,直接触发类型错误。

3. 替换为Ipopt后可运行的原因

Ipopt是纯NLP求解器,会自动将所有Binary域变量松弛为[0,1]区间的连续变量求解。即使变量冗余,Ipopt也会基于初始值(默认取0或初始猜测值)返回一个求解结果,不会出现value为None的情况,因此不会触发报错。

解决方案

如果你的问题确实需要用到z_predicate变量,请补充对应的约束逻辑,确保所有二元变量都参与到约束或目标计算中;如果不需要该变量,直接删除z_predicate的定义和对应的BiConstraint即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 22:24:04