frunk
frunk

Reputation: 15

Pyomo: how to work with 2D arrays or Sets

I have a matrix that carries different integer status per cell. I simply want to constrain each cell by a specific rule but pyomo doesn't comprehend the datatype.

Here's what I have

import pyomo.environ as pe

def assign_server_locations(model, i, j):
    return model[i, j] >= 0 


server_map = [[-1,1],[2,-2],[-3,3]]
model = pe.ConcreteModel()

model.server_x = range(2)
model.server_y = range(3)
model.server_map = pe.Set(dimen = 2, initialize = server_map)
model.c1 = pe.Constraint(model.server_map, model.server_y, model.server_x, rule=assign_server_locations)

the error around the Constraint creation is

TypeError: assign_server_locations() takes 3 positional arguments but 5 were given

How can:

Thanks in advance!

Upvotes: 0

Views: 2522

Answers (1)

AirSquid
AirSquid

Reputation: 11938

Welcome to the site...

You've got a handful of problems there... Briefly:

  • the constraint construction is puking because you are handing it 5 values (the model, 2 for server.map, and x, and y.) and you are only catching 3

  • in your constraint, you have no variable! model[i, j] is going to cause an error. You need to create a properly indexed variable.

  • you are creating some model elements (like model.x and model.y as non-pyomo elements. I'd recommend you keep them as pyomo elements, it helps with troubleshooting.

Here is an example that I think does a bunch of stuff similar to what you are looking for.

import pyomo.environ as pe


matrix_dims = (4, 2)  # row, col
limit_positions = { (2, 1): 2,
                    (1, 0): 1,
                    (3, 1): 2}

model = pe.ConcreteModel()

# SETS
model.server_x = pe.Set(initialize=range(matrix_dims[0]))  # may come in handy to total by rows or such.  Also, make it a pyomo Set
model.server_y = pe.Set(initialize=range(matrix_dims[1]))
model.matrix = pe.Set(initialize=model.server_x*model.server_y)
model.low_positions = pe.Set(within=model.matrix, initialize=limit_positions.keys())   # use of "within" will error-check

# PARAMS
model.limit_positions = pe.Param(model.low_positions, initialize=limit_positions)

# VARS
model.X = pe.Var(model.matrix, domain=pe.NonNegativeReals)

# CONSTRAINTS
# limit all positions to max of 5
def limit_all(model, i, j):
    return model.X[i, j] <= 5
model.C1 = pe.Constraint(model.matrix, rule=limit_all)

# limit the low-positions to their limit...
def limit_lows(model, i, j):
    return model.X[i, j] <= model.limit_positions[i, j]
model.C2 = pe.Constraint(model.low_positions, rule=limit_lows)

model.pprint()

Yields:

4 Set Declarations
    low_positions : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     2 : matrix :    3 : {(2, 1), (1, 0), (3, 1)}
    matrix : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     2 :    Any :    8 : {(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1), (3, 0), (3, 1)}
    server_x : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :    4 : {0, 1, 2, 3}
    server_y : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :    2 : {0, 1}

1 Param Declarations
    limit_positions : Size=3, Index=low_positions, Domain=Any, Default=None, Mutable=False
        Key    : Value
        (1, 0) :     1
        (2, 1) :     2
        (3, 1) :     2

1 Var Declarations
    X : Size=8, Index=matrix
        Key    : Lower : Value : Upper : Fixed : Stale : Domain
        (0, 0) :     0 :  None :  None : False :  True : NonNegativeReals
        (0, 1) :     0 :  None :  None : False :  True : NonNegativeReals
        (1, 0) :     0 :  None :  None : False :  True : NonNegativeReals
        (1, 1) :     0 :  None :  None : False :  True : NonNegativeReals
        (2, 0) :     0 :  None :  None : False :  True : NonNegativeReals
        (2, 1) :     0 :  None :  None : False :  True : NonNegativeReals
        (3, 0) :     0 :  None :  None : False :  True : NonNegativeReals
        (3, 1) :     0 :  None :  None : False :  True : NonNegativeReals

2 Constraint Declarations
    C1 : Size=8, Index=matrix, Active=True
        Key    : Lower : Body   : Upper : Active
        (0, 0) :  -Inf : X[0,0] :   5.0 :   True
        (0, 1) :  -Inf : X[0,1] :   5.0 :   True
        (1, 0) :  -Inf : X[1,0] :   5.0 :   True
        (1, 1) :  -Inf : X[1,1] :   5.0 :   True
        (2, 0) :  -Inf : X[2,0] :   5.0 :   True
        (2, 1) :  -Inf : X[2,1] :   5.0 :   True
        (3, 0) :  -Inf : X[3,0] :   5.0 :   True
        (3, 1) :  -Inf : X[3,1] :   5.0 :   True
    C2 : Size=3, Index=low_positions, Active=True
        Key    : Lower : Body   : Upper : Active
        (1, 0) :  -Inf : X[1,0] :   1.0 :   True
        (2, 1) :  -Inf : X[2,1] :   2.0 :   True
        (3, 1) :  -Inf : X[3,1] :   2.0 :   True

8 Declarations: server_x server_y matrix low_positions limit_positions X C1 C2

Upvotes: 1

Related Questions