2 years ago

#56646

test-img

m_c_frank

Convert OR Tools IntervalVars into Binary List

Good Morning,

I'm trying to find a way to convert IntervalVars into a List of BooleanVars with or tools in order to use the binary list as a sort of field in which the booleans indicate where the Interval is located in the window between time 0 and horizon. I've got it working with just one Interval, i.e. when i print all Solutions it shows the interval in all possible positions:

all combination/solutions:

[
 [0, 0, 1, 1, 0], 
 [0, 1, 1, 0, 0], 
 [0, 0, 0, 1, 1], 
 [1, 1, 0, 0, 0]
]

working model:

    duration = 2
    horizon = 5
    model = cp_model.CpModel()

    bool_vars = []
    start_var = model.NewIntVar(0, horizon, "start")
    interval_var = model.NewFixedSizeIntervalVar(start_var, duration, "interval")

    for i in range(horizon):
        bool_var = model.NewBoolVar(f"bool_{i}")
        model.Add(interval_var.StartExpr() <= i).OnlyEnforceIf(bool_var)
        model.Add(interval_var.EndExpr() > i).OnlyEnforceIf(bool_var)
        bool_vars.append(bool_var)

    model.Add(sum(bool_vars) == duration)

Now if i try to extend this method to two intervals it doesn't work.

    durations = [1,2]
    horizon = 5
    model = cp_model.CpModel()

    bool_vars = [model.NewBoolVar(f"bool_{i}") for i in range(horizon)]

    for duration in durations:
        start_var = model.NewIntVar(0, horizon, f"start_{duration}")
        interval_var = model.NewFixedSizeIntervalVar(start_var, duration, f"interval_{duration}")
        for i in range(horizon):
            model.Add(interval_var.StartExpr() <= i).OnlyEnforceIf(bool_vars[i])
            model.Add(interval_var.EndExpr() > i).OnlyEnforceIf(bool_vars[i])
    model.Add(sum(bool_vars) == sum(durations))

I suspect its the lines

    model.Add(interval_var.StartExpr() <= i).OnlyEnforceIf(bool_var)
    model.Add(interval_var.EndExpr() > i).OnlyEnforceIf(bool_var)

I know theres something fundamental which I'm missing but I cant think of another solution at the moment

Any input and criticism is appreciated! <3

The concrete Problem I'm trying to solve in this current step is:

Modify the current method (utilizing Google OR Tools) such that: given a list of durations and a horizon, find all possible combinations. With the constraint that sequences are separated by a gap/pause with duration_of_gap >= 1.

Example 1:

inputs:
  durations = [1,2]
  horizon = 5
solution:
  combinations = [
 [1, 0, 1, 1, 0], 
 [1, 0, 0, 1, 1], 
 [0, 1, 0, 1, 1], 
]

Example 2:

inputs:
  durations = [3,1,2]
  horizon = 10
solution:
  combinations = [
    [1, 1, 1, 0, 1, 0, 1, 1, 0, 0],
    [1, 1, 1, 0, 1, 0, 0, 1, 1, 0],
    [1, 1, 1, 0, 1, 0, 0, 0, 1, 1],
    [1, 1, 1, 0, 0, 1, 0, 1, 1, 0],
    [1, 1, 1, 0, 0, 1, 0, 0, 1, 1],
    [1, 1, 1, 0, 0, 0, 1, 0, 1, 1],
    [0, 1, 1, 1, 0, 1, 0, 1, 1, 0],
    [0, 1, 1, 1, 0, 1, 0, 0, 1, 1],
    [0, 1, 1, 1, 0, 0, 1, 0, 1, 1],
    [0, 0, 1, 1, 1, 0, 1, 0, 1, 1]
]

python

or-tools

cp-sat-solver

0 Answers

Your Answer

Accepted video resources