Search code examples
optimizationconstraintspyomo

How to make the right constraints in optimization problem in pyomo


I have an optimization problem of wagons repairs.

  'Lon':   125,        # London
  'Ber':   175,        # Berlin
  'Maa':   225,        # Maastricht
  'Ams':   250,        # Amsterdam
  'Utr':   225,        # Utrecht
  'Hag':   200         # The Hague
}

Supply = {
  'Arn':   600,        # Arnhem
  'Gou':   650         # Gouda
}

T = {
   ('Lon','Arn'): 1000,
   ('Lon','Gou'): 2.5,
   ('Ber','Arn'): 2.5,
   ('Ber','Gou'): 1000,
   ('Maa','Arn'): 1.6,
   ('Maa','Gou'): 2.0,
   ('Ams','Arn'): 1.4,
   ('Utr','Arn'): 0.8,
   ('Utr','Gou'): 1.0,
   ('Hag','Arn'): 1.4,
   ('Hag','Gou'): 0.8
} 

T is a cost for all permitted routes. I defined the model and objective function.

# Step 0: Create an instance of the model
model = ConcreteModel()
model.dual = Suffix(direction=Suffix.IMPORT)

# Step 1: Define index sets
CUS = list(Demand.keys())
SRC = list(Supply.keys())

# Step 2: Define the decision 
model.x = Var(list(T), domain = NonNegativeReals)

# Step 3: Define Objective
model.Cost = Objective(
    expr = sum([T[i]*model.x[i] for i in model.x]),
    sense = minimize)

But I have problems with constraints. If I am doing as shown below it throws an error.

# Step 4: Constraints
model.src = ConstraintList()
for s in SRC:
   model.src.add(sum([model.x[c,s] for c in CUS]) <= Supply[s])
       
model.dmd = ConstraintList()
for c in CUS:
   model.dmd.add(sum([model.x[c,s] for s in SRC]) == Demand[c])

Error is like that:

enter image description here

Maybe anyone knows how to fix the problem with constraints. To make it more flexible. I understand why it is an error because in T there are not all possible combinations, but it is right, some of the routes is restricted and I do not want to use them in optimization.


Solution

  • You can first get the possible ones like this:

    # Step 4: Constraints
    model.src = ConstraintList()
    for s in SRC:
        cposs = [t[0] for t in T.keys() if t[1] == s]
        model.src.add(sum([model.x[c,s] for c in cposs]) <= Supply[s])
    
    model.dmd = ConstraintList()
    for c in CUS:
        sposs = [t[1] for t in T.keys() if t[0] == c]
        model.dmd.add(sum([model.x[c,s] for s in sposs]) == Demand[c])