J'essaie de résoudre un problème d'optimisation non linéaire de contraintes mixtes entières en utilisant PyOMO. Plus précisément, j'essaie de trouver les diamètres des engrenages et les nombres de dents de telle sorte que deux rapports d'engrenages donnés soient respectés. Je suis vraiment très confus sur la façon d'utiliser Set()
et Var()
. J'ai lu la documentation mais ce n'est pas super super clair sur ce qu'est réellement un Set! Est-ce un index que je peux utiliser pour accéder à des parties du problème de même type? Voici mon code: (Python 3,5)Pyomo ValueError: PositiveReals n'est pas un domaine valide
from pyomo.environ import *
from pyomo.opt import SolverFactory
import numpy as np
# Define Forward and Reverse Gear Ratios
fwd_ratio = 4.3
rev_ratio = 9.1
D_guess = [4.5, 11.5, 6.0, 10.0, 4.5, 2.5, 2.25, 9.0]
N_guess = [18, 46, 24, 40, 18, 20, 18, 72]
idx = np.arange(0,8)
print(idx)
model = AbstractModel()
# Declare Model Sets??? I tried this as first argument to Var(), didn't work
#model.Didx = Set(D_guess)
#model.Nidx = Set(N_guess)
# Declare Model Variables
model.D = Var(D_guess, within='PositiveReals', bounds=(1.0,None))
model.N = Var(N_guess, within='PositiveInteger', bounds=(18,None))
# Declare Objective Functions
def obj_funcD(model):
F1 = (model.D[1]/model.D[0])*(model.D[3]/model.D[2]) - fwd_ratio
F2 = (model.D[1]/model.D[4])*(model.D[6]/model.D[5])*(model.D[7]/model.D[6]) - rev_ratio
return F1 + F2
def obj_funcN(model):
F1 = (model.N[1]/model.N[0])*(model.N[3]/model.N[2]) - fwd_ratio
F2 = (model.N[1]/model.N[4])*(model.N[6]/model.N[5])*(model.N[7]/model.N[6]) - rev_ratio
return F1 + F2
# Declare Constraint
def con_func1(model):
return model.D[1]/model.D[0] == model.N[1]/model.N[0]
def con_func2(model):
return model.D[3]/model.D[2] == model.N[3]/model.N[3]
def con_func3(model):
return model.D[1]/model.D[4] == model.N[1]/model.N[4]
def con_func4(model):
return model.D[6]/model.D[5] == model.N[6]/model.N[5]
def con_func5(model):
return model.D[7]/model.D[6] == model.N[7]/model.N[6]
# Create Constraint List
model.c1 = Constraint(rule=con_func1)
model.c2 = Constraint(rule=con_func2)
model.c3 = Constraint(rule=con_func3)
model.c4 = Constraint(rule=con_func4)
model.c5 = Constraint(rule=con_func5)
# Create Objectives
model.obj1 = Objective(rule=obj_funcD,sense='minimize')
model.obj2 = Objective(rule=obj_funcN,sense='minimize')
# Solve the Problem?
opt = SolverFactory('glpk')
instance = model.create_instance()
results = opt.solve(instance)
Ce code donne l'erreur suivante:
WARNING: Element 4.5 already exists in set D_index; no action taken.
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pyomo/core/base/PyomoModel.py", line 920, in _initialize_component
ERROR: Constructing component 'D' from data=None failed:
declaration.construct(data)
ValueError: PositiveReals is not a valid domain. Variable domains must be an instance of one of (<class 'pyomo.core.base.set_types.RealSet' at 0x1004bee98>, <class 'pyomo.core.base.set_types.IntegerSet' at 0x1004f2558>, <class 'pyomo.core.base.set_types.BooleanSet' at 0x1004f28f8>), or an object that declares a method for bounds (like a Pyomo Set). Examples: NonNegativeReals, Integers, Binary
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pyomo/core/base/var.py", line 573, in construct
component=None)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pyomo/core/base/var.py", line 299, in __init__
"Integers, Binary" % (domain, (RealSet, IntegerSet, BooleanSet)))
ValueError: PositiveReals is not a valid d
J'ai aussi essayé d'utiliser RangeSet()
et passer l'ensemble associé comme premier argument de Var()
mais ne fait rien non plus! Je savais qu'il me manquait quelque chose de super évident ici mais j'ai regardé l'écran pendant 4 heures maintenant et je sollicite votre aide! Merci