Why always come default value from RangeSet to the constraint in Pyomo?

28 Views Asked by At

I couldn't have i+1 value for the last value of the RangeSet, therefore I want to ignore it in the constraint. However, I couldn't do that because i value always comes as default value. So, it does not enter to if statement. How can I solve the problem ?

import pyomo.environ as pyo
from pyomo.opt import SolverFactory

model = pyo.AbstractModel()

number_of_lane=2
number_of_vehicle=2

model.i = pyo.Param(within=pyo.NonNegativeIntegers, default=number_of_lane)
model.j = pyo.Param(within=pyo.NonNegativeIntegers, default=number_of_vehicle)

model.I = pyo.RangeSet(1, model.i)
model.J = pyo.RangeSet(1, model.j)

model.R = pyo.Param(default=0.5) #CAV's reaction (s)
model.D = pyo.Param(default=1.5) #Safety Distance (m)
model.lv = pyo.Param(default=4) #Length of vehicle (m)

model.xr = pyo.Param(model.I, model.J, within=pyo.NonNegativeIntegers, initialize=xr_cons)
model.x = pyo.Var(model.I, model.J, domain=pyo.NonNegativeReals, initialize=(0))

def lane_crossing_constraint_rule(m, i, j): #lane should be 2, vehicles will be the first one which is close to the intersection
    m.i.pprint() #There is a problem about taking i and j value
    if(m.i.value<number_of_vehicle): #Always comes equal!!!!
        return (m.x[i,j]-m.xr[i,j])**2+(m.x[i+1,j]-m.xr[i+1,j])**2>=(m.lv+m.D)
    else:
        return pyo.Constraint.Skip

# the next line creates one constraint for each member of the set model.I
model.l1Constraint = pyo.Constraint(model.I, model.J, rule=lane_crossing_constraint_rule)
2

There are 2 best solutions below

1
AirSquid On BEST ANSWER

It isn't super clear what you are trying to do with the model setup you've chosen. Why did you select AbstractModel()? Your example isn't reproducible because it is missing data and you aren't building a model instance. Further, I'm not sure what you are trying to accomplish by initializing your range set size from the value of a parameter?

I think you should start with a ConcreteModel(), get something working, and build out from there, if needed. Build a little bit at a time, print the model and verify it, then add to it.

Here is a small example that I think shows some of the things you are trying to do. It is a ConcreteModel that builds a range set, a variable, and shows how to make a constraint that is dependent on the value of the index from the set Lanes

import pyomo.environ as pyo
from pyomo.opt import SolverFactory

model = pyo.ConcreteModel()

number_of_lanes = 5

model.Lanes = pyo.RangeSet(1, number_of_lanes)

model.car_speed = pyo.Var(model.Lanes, domain=pyo.NonNegativeReals)


def lane_speed(model, lane):
    if lane < 4:
        return model.car_speed[lane] <= 60
    return pyo.Constraint.Skip


model.lane_speed = pyo.Constraint(model.Lanes, rule=lane_speed)

model.pprint()

Output

1 RangeSet Declarations
    Lanes : Dimen=1, Size=5, Bounds=(1, 5)
        Key  : Finite : Members
        None :   True :   [1:5]

1 Var Declarations
    car_speed : Size=5, Index=Lanes
        Key : Lower : Value : Upper : Fixed : Stale : Domain
          1 :     0 :  None :  None : False :  True : NonNegativeReals
          2 :     0 :  None :  None : False :  True : NonNegativeReals
          3 :     0 :  None :  None : False :  True : NonNegativeReals
          4 :     0 :  None :  None : False :  True : NonNegativeReals
          5 :     0 :  None :  None : False :  True : NonNegativeReals

1 Constraint Declarations
    lane_speed : Size=3, Index=Lanes, Active=True
        Key : Lower : Body         : Upper : Active
          1 :  -Inf : car_speed[1] :  60.0 :   True
          2 :  -Inf : car_speed[2] :  60.0 :   True
          3 :  -Inf : car_speed[3] :  60.0 :   True

3 Declarations: Lanes car_speed lane_speed
0
unknownperson On

I solved. Thanks to AirSquid for an example.

The solution:

def lane_crossing_constraint_rule(m, i, j): #lane should be 2, vehicles will be the first one which is close to the intersection
    if(i <number_of_vehicle):
        return (m.x[i,j]-m.xr[i,j])**2+(m.x[i+1,j]-m.xr[i+1,j])**2>=(m.lv+m.D)
    else:
        return pyo.Constraint.Skip