Pyomo对NoneType使用__round__方法



我正在使用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:usershongkappdatalocalprogramspythonpython36libsite-packagespyomocontribmindtpyMindtPy.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:usershongkappdatalocalprogramspythonpython36libsite-packagespyomocontribmindtpyiterate.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:usershongkappdatalocalprogramspythonpython36libsite-packagespyomocontribmindtpyiterate.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:usershongkappdatalocalprogramspythonpython36libsite-packagespyomocontribmindtpyutil.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

我试着把模型注释掉。将最后两行替换为

solver = pyomo.opt.SolverFactory('ipopt')
results = solver.solve(model, tee=True)

结果很好。所以我猜错误来自model. bicconstraint .

有人知道Pyomo为什么这样做吗?我无法从任何Pyomo材料中找到原因。

我的配置。Python 3.6.13:: Anaconda, IncPyomo 6.1.2 (Windows 10上的CPython 3.6.13)gurobi 9.1.1ipopt 3.11.1mindtpy 0.1

您的求解器设置....有一些奇怪的地方我不熟悉使用mindpy

的这种设置这个可以正常工作:

solver = pe.SolverFactory('ipopt')
results = solver.solve(model)
print(results)
model.display()

进一步更新……您的原始问题似乎与您的z_predicate变量的一部分在您的模型中根本没有引用这一事实有关,特别是当M=2时。这就导致它们变得"陈旧"。我认为这是导致mindpy呕吐的原因。如果您将约束更改为:

model.BiConstraint = pe.Constraint(model.T,model.M,rule=binary_constraint)

mindpy做的事情很好。还请注意,由于z_predicate未使用,此约束在您的模型中不活跃。

@JohnSmith

问题是mindtpy试图将round()函数应用于None值。现在,None值出现了,有效地来自以下内容:

你正在模拟model.z_predicate = pe.Var(model.T, model.M, domain=pe.Binary)model.M = pe.RangeSet(1,2)的问题是,你没有给model.z_predicate[model.T, 2]分配任何值,因为在你的约束中,你只在binary_constraint

中约束model.z_predicate[model.T, 1]

你可以用它做两件事:

  1. 删除model.M未使用的索引:

    model.M = pe.RangeSet(1)
    
  2. 使用model.z_predicate的初始值:

    model.z_predicate = pe.Var(model.T, model.M, domain=pe.Binary, initialize=0)
    

通过这两种方式,您都避免了NoneType轮问题并获得了解决方案。在我的情况下(我不知道是否可以)是:

INFO: ---Starting MindtPy---
INFO: Original model has 21 constraints (8 nonlinear) and 0 disjunctions, with
28 variables, of which 5 are binary, 0 are integer, and 23 are continuous.
INFO: Objective is nonlinear. Moving it to constraint set.
INFO: rNLP is the initial strategy being used.
INFO: NLP 1: Solve relaxed integrality
INFO: NLP 1: OBJ: 0.0  LB: -inf  UB: inf
INFO: ---MindtPy Master Iteration 0---
INFO: MIP 1: Solve master problem.
INFO: MIP 1: OBJ: 0.0  LB: 0.0  UB: inf
INFO: NLP 2: Solve subproblem for fixed binaries.
INFO: NLP 2: OBJ: 0.0  LB: 0.0  UB: 0.0
INFO: MindtPy exiting on bound convergence. LB: 0.0 + (tol 0.0001) >= UB: 0.0
>>>model.OBJ.expr()
1.286551594275684e-09

相关内容

  • 没有找到相关文章

最新更新