CP constraint error

451 views
Skip to first unread message

alexandre...@gmail.com

unread,
Mar 5, 2022, 12:58:26 PM3/5/22
to or-tools-discuss
Hello, I am using the CP library to solve a problem, and one of my constraint keeps returning the same error, after many trials of modifying the data types or constraint format...

I am building a task scheduling model with task successors and time horizon, here are my params/variables:

alltask = len(tasklist)  // list of about 63 tasks
allhorizon =len(horizonlist) // list of about 400 points each one considered a 'day' for example
duration[i] = a list of durations for task i

i = task
j = horizon
l = successors

    for i in range(alltasks):
        for j in range(allhorizon):
            start[i,j] = model.NewBoolVar("start[i,j]") // variable will equal 1 if task i starts on period j

Now the constraint in question that's causing me a problem:
    for i in range(alltasks-1):
        for j in range(allhorizon):
            for l in range(len(successor)):
                model.Add(start[i,j]*j+duration[i] >= start[successor[i,l],j]*j)
I have a successor Pandas Series filled with tuples.
the i axis is the task list
the j axis it the successor list
I am multiplying start[] and successor[] by *j so that it returns the actual time period.

for example:
successor[2,3] is the tuple that returns the 4th task successor to the 2nd task.
by doing start[]*j+duration[i], it returns the end period of task i (since j is 1,2,...,horizon)
So the constraint will make it impossible for a successor task to start on a given period as long as the predecessor isn't finish.

I get the error:
KeyError: 'key of type tuple not found and not a MultiIndex'

Any idea what's causing this?
It's for sure ''start[successor[i,l],j]], i just don't know why.

Thank you

Laurent Perron

unread,
Mar 5, 2022, 1:20:09 PM3/5/22
to or-tools-discuss
Cast to int maybe. 

--
You received this message because you are subscribed to the Google Groups "or-tools-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to or-tools-discu...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/or-tools-discuss/9f80830b-7500-4f94-96b4-a7eccf9f6680n%40googlegroups.com.
Message has been deleted
Message has been deleted

alexandre...@gmail.com

unread,
Mar 9, 2022, 2:29:25 PM3/9/22
to or-tools-discuss
(Sorry for the multiple deleted messages, I just found out about the AddElement constraint and adjusted my questioning):

I have a list of 63 tasks:
start[i,j] is a boolvar = 1 if task i starts on period j

Most tasks have successors (these can't start until task i is completed). Some tasks have more than 1 successors.
successor[i,L] = task L is a successor of task i. L ranges from 1 to 10.

In MiniZinc, you could do something like this to access the successor index and add the constraint:
start[i,j] + duration[i] <= start[successor[i,L],j]

How can I do this with the AddElement constraint? I'm not sure I understand the index/variable/target arguments if start and successor are not 1D.

Laurent Perron

unread,
Mar 9, 2022, 2:39:49 PM3/9/22
to or-tools-discuss
Why don't you look at this example: https://github.com/google/or-tools/blob/stable/examples/python/jobshop_ft06_distance_sat.py

What you are doing seems awfully complicated.
Laurent Perron | Operations Research | lpe...@google.com | (33) 1 42 68 53 00



alexandre...@gmail.com

unread,
Mar 12, 2022, 3:24:58 PM3/12/22
to or-tools-discuss
I managed to make it work by removing the notion of period and putting start[i] as a integer var (like jobshop as you suggested). The successor tuple now works perfectly.

I'm now trying to fill a dataframe with 1 or 0 depending if the task is between it's start period and it's end period

ex: task 1 starts on period 3 and ends on period 6
I want active_matrix['period'] = 1 for period = 3, 4, 5, 6 (active_matrix['period'] has as many periods as all my tasks

I am approaching this correctly with this method?:
            model.Add(start[i] <= active_matrix.loc[i,'Period']).OnlyEnforceIf(control)
            model.Add(start[i]+duration[i] >= active_matrix.loc[i,'Period']).OnlyEnforceIf(control)

            model.Add(active_matrix.loc[i,'Period'] == 0).OnlyEnforceIf(control.Not())
            model.Add(active_matrix.loc[i,'Period'] == 1).OnlyEnforceIf(control)

I tried doing this:
if(active_matrix.loc[i,'Period'] >= start[i]):
                if(active_matrix.loc[i,'Period'] <= start[i]+duration[i]):
                    active_matrix.loc[i,'TaskWIP'] == 1
            else: active_matrix.loc[i,'TaskWIP'] == 0

But I get an error: Evaluating a BoundedLinearExpression 'start_0 <= 1' as a Boolean value is not supported.

Any insight would be appreciated.
AC

Laurent Perron

unread,
Mar 13, 2022, 11:08:20 AM3/13/22
to or-tools-discuss
You are mixing variables and equations on one side, and solutions on the other side. 

To fill the data frame after the solve, you need to query the values of the variables from the solver. 


Laurent Perron | Operations Research | lpe...@google.com | (33) 1 42 68 53 00


Reply all
Reply to author
Forward
0 new messages