0

Is there a way of changing the values of a constraint as the solver is running?

Basically, I have a constraint that depends on the value of a variable. The problem is that the constraint is evaluated based on the initial value of the variable, but isn't updated as the variable changes.

Here's a simple example:

from pyomo.environ import *
from pyomo.opt import SolverFactory
import numpy as np

# Setup
model = ConcreteModel()
model.A = Set(initialize = [0,1,2])
model.B = Set(initialize = [0,1,2])
model.x = Var(model.A, model.B, initialize=0)

# A constraint that I'd like to keep updating, based on the value of x
def changing_constraint_rule(model, a):
    x_values = list((model.x[a, b].value for b in model.B))
    if np.max(x_values) == 0:
        return Constraint.Skip
    else:
        # Not really important what goes here, just as long as it updates the constraint list
        if a == 1 : return sum(model.x[a,b] for b in model.B) == 0
        else:       return sum(model.x[a,b] for b in model.B) == 1
model.changing_constraint = Constraint(model.A, rule = changing_constraint_rule)

# Another constraint that changes the value of x
def bounding_constraint_rule(model, a):
    return sum(model.x[a, b] for b in model.B) == 1
model.bounding_constraint = Constraint(
    model.A,
    rule = bounding_constraint_rule)

# Some objective function
def obj_rule(model):
    return(sum(model.x[a,b] for a in model.A for b in model.B))
model.objective = Objective(rule=obj_rule)

# Results
opt = SolverFactory("glpk")
results = opt.solve(model)
results.write()
model.x.display()

If I run model.changing_constraint.pprint() I can see that no constraints have been made, since the initial value of the variable model.x was set to 0.

If it's not possible to change the constraint values while solving, how could I formulate this problem differently to achieve what I'm looking for? I've read this other post but couldn't figure it out from the instructions.

1 Answer 1

2

I am giving you the same answer in the other question by @Gabe:

Any if-logic you use inside of rules should not involve the values of variables (unless it is based on the initial value of a variable, in which case you would wrap the variable in value() wherever you use it outside of the main expression that is returned).

for example: model.x[a, b].value should be model.x[a, b].value()

But still this might not give you the solution what you are looking for.

Sign up to request clarification or add additional context in comments.

1 Comment

alas, I think it won't. Thanks for your reply anyway

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.