You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have been implementing a mathematical model using pyomo and recently found out that it would be very convenient for me to use tuples as set members. However, I quickly discovered that pyomo unloads the tuple into its basic elements, requiring me to change my code or possibly use another type of set members.
The problem is that the solution proposed therein is to ignore the issue by disabling checks (namely by adjusting the dimension parameter), not really solving the fact that tuples are not recognised as set members.
I suppose this is not a dealbreaker but it is quite annoying and counter-intuitive because Python does not behave that way.
Steps to reproduce the issue
from pyomo.environ import *
model = ConcreteModel()
CHOICES = [((1,2,3), 4,3), ((1,2,2), 4,3), ((1,3,3), 4,3)]
print(CHOICES)
print('According to Python:')
for set_member in CHOICES:
print('set_member ' + str(set_member)+' has size ' +str(len(set_member)))
print('************************')
print('Let\'s try to create sets with tuples as set members.')
try:
model.S_CHOICES = Set(dimen=3, initialize=CHOICES)
print("Set creation complete.")
except ValueError:
print('************************')
print('Python and Pyomo behave differently with nested tuples.')
model.del_component(model.S_CHOICES)
try:
model.S_CHOICES = Set(dimen=5, initialize=CHOICES)
print("Pyomo unloads tuples automatically. Python does not.")
except ValueError:
print('************************')
print('This message should not be `printed.')
Error Message
ERROR: Constructing component 'S_CHOICES' from data=None failed: ValueError:
The value=((1, 2, 3), 4, 3) has dimension 5 and is not valid for Set
S_CHOICES which has dimen=3
Information on your system
Pyomo version: 6.2
Python version: 3.8.10
Operating system: Ubuntu 20.04 LTS
How Pyomo was installed (PyPI, conda, source): pip
Solver (if applicable): Not necessary
The text was updated successfully, but these errors were encountered:
There is a way to turn off this behavior in Pyomo:
from pyomo.environ import *
# This disables tuple flattening in Pyomo component indices
pyomo.core.base.indexed_component.normalize_index.flatten = False
model = ConcreteModel()
CHOICES = [((1,2,3), 4,3), ((1,2,2), 4,3), ((1,3,3), 4,3)]
print(CHOICES)
print('According to Python:')
for set_member in CHOICES:
print('set_member ' + str(set_member)+' has size ' +str(len(set_member)))
print('************************')
print('Let\'s try to create sets with tuples as set members.')
model.S_CHOICES = Set(initialize=CHOICES)
print("Set creation complete.")
The caveat is that you have to be very careful when using the model.S_CHOICES set. In particular, when writing indexed constraint rules note that ((1,2,3),4,3) will be passed in as 3 arguments, (i, j, k), to the rule. Also, be careful using more advanced features of Pyomo such as some of the domain-specific modeling extensions and transformations. It's possible that some of these features assume the default index flattening behavior.
For a more detailed explanation on why tuple flattening is the default behavior in Pyomo and some of the design considerations that went into the Pyomo Set component, see #326. In particular the bullet point starting with "How should we handle 1-tuples?".
Summary
I have been implementing a mathematical model using pyomo and recently found out that it would be very convenient for me to use tuples as set members. However, I quickly discovered that pyomo unloads the tuple into its basic elements, requiring me to change my code or possibly use another type of set members.
I found an earlier reference to this in: #142 (comment)
The problem is that the solution proposed therein is to ignore the issue by disabling checks (namely by adjusting the dimension parameter), not really solving the fact that tuples are not recognised as set members.
I suppose this is not a dealbreaker but it is quite annoying and counter-intuitive because Python does not behave that way.
Steps to reproduce the issue
Error Message
ERROR: Constructing component 'S_CHOICES' from data=None failed: ValueError:
The value=((1, 2, 3), 4, 3) has dimension 5 and is not valid for Set
S_CHOICES which has dimen=3
Information on your system
Pyomo version: 6.2
Python version: 3.8.10
Operating system: Ubuntu 20.04 LTS
How Pyomo was installed (PyPI, conda, source): pip
Solver (if applicable): Not necessary
The text was updated successfully, but these errors were encountered: