Open thisandthatuser opened 3 weeks ago
Pyomo Set objects allow users to define their supersets for validation via the within argument. This used to be possible with indexed set too (objects (e.g., pyomo 6.6) but is no longer possible.
The following script can be used to reproduce the issue. I adapted the example from the website (https://pyomo.readthedocs.io/en/stable/pyomo_modeling_components/Sets.html).
import pyomo.environ as pyo from pyomo.opt import check_available_solvers use_within_argument = False # change to True to trigger the error model = pyo.AbstractModel() # non-indexed sets not using the within argument model.Nodes = pyo.Set() model.Arcs = pyo.Set(dimen=2) # non-indexed sets using within argument model.SubsetNodes = pyo.Set(within=model.Nodes) model.SubsetArcs = pyo.Set(within=model.Arcs, dimen=2) # indexed sets not using the within argument model.ThingsOfArcs = pyo.Set(model.Arcs) model.ThingsOfNodes = pyo.Set(model.Nodes) # indexed sets using the within/not using the argument if not use_within_argument: # okay model.SubsetThingsOfNodes = pyo.Set(model.Nodes) model.SubsetThingsOfArcs = pyo.Set(model.Arcs) else: # fail model.SubsetThingsOfNodes = pyo.Set(model.Nodes, within=model.ThingsOfNodes) model.SubsetThingsOfArcs = pyo.Set(model.Arcs, within=model.ThingsOfArcs) def NodesOut_init(m, node): for i, j in m.Arcs: if i == node: yield j model.NodesOut = pyo.Set(model.Nodes, initialize=NodesOut_init) def NodesIn_init(m, node): for i, j in m.Arcs: if j == node: yield i model.NodesIn = pyo.Set(model.Nodes, initialize=NodesIn_init) model.Flow = pyo.Var(model.Arcs, domain=pyo.NonNegativeReals) model.FlowCost = pyo.Param(model.Arcs) model.Demand = pyo.Param(model.Nodes) model.Supply = pyo.Param(model.Nodes) def Obj_rule(m): return pyo.summation(m.FlowCost, m.Flow) model.Obj = pyo.Objective(rule=Obj_rule, sense=pyo.minimize) def FlowBalance_rule(m, node): return m.Supply[node] \ + sum(m.Flow[i, node] for i in m.NodesIn[node]) \ - m.Demand[node] \ - sum(m.Flow[node, j] for j in m.NodesOut[node]) \ == 0 model.FlowBalance = pyo.Constraint(model.Nodes, rule=FlowBalance_rule) data_dict = { None: { 'Arcs': {None: [("CityA","CityB"), ("CityA", "CityC"), ("CityC", "CityB")]}, 'Nodes': {None: ["CityA", "CityB", "CityC"]}, 'FlowCost': {("CityA","CityB"): 1.4, ("CityA", "CityC"): 2.7, ("CityC", "CityB"): 1.6}, 'Demand': {"CityA":0, "CityB": 1, "CityC": 1}, 'Supply': {"CityA": 2, "CityB": 0, "CityC": 0}, # new data 'SubsetNodes': {None: ["CityC"]}, 'SubsetArcs': {None: [("CityA","CityB"),("CityC", "CityB")]}, 'ThingsOfNodes': {"CityA": ['a','b','c'], "CityB": ['d', 'e', 'f'], "CityC": ['a','d']}, 'ThingsOfArcs': {("CityA","CityB"): ['m','h'], ("CityA", "CityC"): ['t','g'], ("CityC", "CityB"): ['r']}, 'SubsetThingsOfNodes': {"CityA": ['a','c'], "CityB": ['f'], "CityC": ['d']}, 'SubsetThingsOfArcs': {("CityA","CityB"): ['h'], ("CityA", "CityC"): ['t'], ("CityC", "CityB"): ['r']}, } } solver_name = 'cbc' solver_available = bool(check_available_solvers(solver_name)) if solver_available: opt = pyo.SolverFactory(solver_name) problem = model.create_instance(data=data_dict) opt.solve(problem, tee=True)
$ ERROR: Constructing component 'SubsetThingsOfNodes' from data={'CityA': ['a', 'c'], 'CityB': ['f'], 'CityC': ['d']} failed: AttributeError: 'InsertionOrderSetData' object has no attribute 'construct' Traceback (most recent call last): File ~\Documents\Trabalho\Python\pyvenv\lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec exec(code, globals, locals) File c:\users\mend_pd\documents\trabalho\example\ptomo_sparse_set.py:112 problem = model.create_instance(data=data_dict) File ~\Documents\Trabalho\Python\pyvenv\lib\site-packages\pyomo\core\base\PyomoModel.py:731 in create_instance instance.load(data, namespaces=_namespaces, profile_memory=profile_memory) File ~\Documents\Trabalho\Python\pyvenv\lib\site-packages\pyomo\core\base\PyomoModel.py:768 in load self._load_model_data(dp, namespaces, profile_memory=profile_memory) File ~\Documents\Trabalho\Python\pyvenv\lib\site-packages\pyomo\core\base\PyomoModel.py:820 in _load_model_data self._initialize_component( File ~\Documents\Trabalho\Python\pyvenv\lib\site-packages\pyomo\core\base\PyomoModel.py:868 in _initialize_component declaration.construct(data) File ~\Documents\Trabalho\Python\pyvenv\lib\site-packages\pyomo\core\base\set.py:2181 in construct IndexedComponent.__getitem__(self, index) File ~\Documents\Trabalho\Python\pyvenv\lib\site-packages\pyomo\core\base\indexed_component.py:658 in __getitem__ return self._getitem_when_not_present(index) File ~\Documents\Trabalho\Python\pyvenv\lib\site-packages\pyomo\core\base\set.py:2221 in _getitem_when_not_present domain.construct() AttributeError: 'InsertionOrderSetData' object has no attribute 'construct'
Pyomo version: 6.7.3 Python version: 3.10.6 Operating system: Windows 10 How Pyomo was installed (PyPI, conda, source): pip Solver (if applicable): cbc, scip, etc
I ran into this error when I upgraded to pyomo 6.7.3. The error should not be obtained with pyomo 6.6.x and earlier versions.
Summary
Pyomo Set objects allow users to define their supersets for validation via the within argument. This used to be possible with indexed set too (objects (e.g., pyomo 6.6) but is no longer possible.
Steps to reproduce the issue
The following script can be used to reproduce the issue. I adapted the example from the website (https://pyomo.readthedocs.io/en/stable/pyomo_modeling_components/Sets.html).
Error Message
Information on your system
Pyomo version: 6.7.3 Python version: 3.10.6 Operating system: Windows 10 How Pyomo was installed (PyPI, conda, source): pip Solver (if applicable): cbc, scip, etc
Additional information
I ran into this error when I upgraded to pyomo 6.7.3. The error should not be obtained with pyomo 6.6.x and earlier versions.