我正在使用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]
你可以用它做两件事:
删除
model.M
未使用的索引:model.M = pe.RangeSet(1)
使用
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