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

Pyomo does not allow for tuples to be set members #2423

Closed
pmlpm1986 opened this issue May 30, 2022 · 1 comment
Closed

Pyomo does not allow for tuples to be set members #2423

pmlpm1986 opened this issue May 30, 2022 · 1 comment

Comments

@pmlpm1986
Copy link
Contributor

pmlpm1986 commented May 30, 2022

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

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

@blnicho
Copy link
Member

blnicho commented May 30, 2022

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?".

@blnicho blnicho closed this as completed May 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants