Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IndexedSet objects can no longer be used with the within argument in pyomo 6.7.3 #3284

Closed
thisandthatuser opened this issue Jun 6, 2024 · 0 comments · Fixed by #3288
Closed
Labels

Comments

@thisandthatuser
Copy link
Contributor

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).

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 Message

$ 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'

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1 participant