Closed gustavo-barros closed 5 years ago
Pre-compute which tasks can be splitted, create more than 1 intervals. (2 in your case), constraint the sum of durations to be the total duration. Do you need something else ?
And as I said in another mail, please use the CP-SAT solver. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le ven. 26 avr. 2019 à 21:15, gustavo-barros notifications@github.com a écrit :
Hi,
I'm trying to solve a jobShop like problem for a factory floor operations scheduling. I'm using CPSolver.
The problem is that I have a factory Plant that works on a set of predefined work shifts. Each machine can have it's own work shift for each day of the calendar. So I configure the model to distribute the operations only in the allowed time period.
The difficult part happens when there is a operation length that exceeds the length of the available work shift time. The solver simply move the entire operation to the next day shift or next allowed time space. So I was wondering, is there a way to make the solver split the operation between two work shifts?
See the image below, the orange blocks are the allowed ones defined in the machine shift for that specific day. The purple ones are not allowed to be used because is the time that the factory shutdown. The blue block (30002/1) for example is a block that I wanted to be splitted, because it has no dependencies and there is a free space at it's left as shown in the image:
[image: image] https://user-images.githubusercontent.com/36746102/56830314-67c80900-683c-11e9-991a-eb3800b482b9.png
After this procedure, the result should be something like this image below, and this behaviour should be applied to each operation that fits in this case and are longer than the available space:
[image: image] https://user-images.githubusercontent.com/36746102/56830402-9d6cf200-683c-11e9-9170-1df064f69175.png
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3PHNQUNJQTLACP4YYTPSNIDPANCNFSM4HIZUSHA .
Pre-compute which tasks can be splitted, create more than 1 intervals. (2 ...
@lperron Does this mean that we will need to split every task by a single unit of time and group them using a constraint?
Ie: task that lasts 3 units of time, will turn into 3 tasks of 1 unit of time each??
What if we have 5000 tasks? Won’t the solver take a long time to solve?
I don’t know if I understood your answer correctly.. any simple example code would be much appreciated..
Thanks!!
Sent with GitHawk
no, if a task duration is less than <= 2 x the smallest time span, split it in 2. Force the duration of the first interval to be at least one. Make the second optional. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le sam. 27 avr. 2019 à 15:22, EduSikora notifications@github.com a écrit :
Pre-compute which tasks can be splitted, create more than 1 intervals. (2 ...
@lperron https://github.com/lperron Does this mean that we will need to split every task by a single unit of time and group the using a constraint?
Ie: task that lasts 3 units of time, will turn into 3 tasks of 1 unit of time each??
What if we have 5000 tasks? Won’t the solver take a long time to solve?
I don’t know if I understood your answer correctly.. any simple example code would be much appreciated..
Thanks!!
Sent with GitHawk http://githawk.com
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223#issuecomment-487285829, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3KEVG2HTBJDODEB5PDPSRHRVANCNFSM4HIZUSHA .
Hi Iperron,
Thank you for your reply.
I didn't understand your solution. The problem is that we can only know if a task should be splitted after it was distributed using the solver. We are trying to avoid running the solver, making adjustments and running it again. We need to be efficient.
If we pre-compute, we would not know wich one to split in advance. And even if we apply a splitting logic over all tasks at the beginning we would end up with thousands of tasks, at least the double of the total amount, right? Because most of then have length <= 2xSmallestTimeSpan. That's probably would be impractical because we want to tackle large problems.
How can we achieve this behaviour using the solver?
We are currently setting the disabled periods (purple) like this:
where: and
key = startTime deactivatedPeriod = duration.
Then we run this:
Where:
_DataProcessor.GetOdfsCount() returns the jobs count
So the solver knows where not to put the tasks. There is another way that would help we achieve the mentioned behaviour? Or this would not change anything?
We need this functionallity to be able to use ORTools solver in our project.
In previous threads on the mailing list, I discussed the options for having tasks spanning across breaks. That is a task interrupted by a break would resume as soon as the breaks stop ?
Would you be interested in that ?
Now, about the split green block. You could force all blocks to belong to different break structure. For instance impose a min distance between split tasks, or having one optional tasks per work period and per task.
You also post-process the solution to merge the green blocks.
Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le lun. 29 avr. 2019 à 15:50, gustavo-barros notifications@github.com a écrit :
Hi Iperron,
Thank you for your reply.
I didn't understand your solution. The problem is that we can only know if a task should be splitted after it was distributed using the solver. We are trying to avoid running the solver, making adjustments and running it again. We need to be efficient.
If we pre-compute, we would not know wich one to split in advance. And even if we apply a splitting logic over all tasks at the beginning we would end up with thousands of tasks, at least the double of the total amount, right? Because most of then have length <= 2xSmallestTimeSpan. That's probably would be impractical because we want to tackle large problems.
How can we achieve this behaviour using the solver?
[image: image] https://user-images.githubusercontent.com/36746102/56898389-4d25a800-6a67-11e9-8459-9db053c61581.png
We are currently setting the disabled periods (purple) like this:
[image: image] https://user-images.githubusercontent.com/36746102/56899290-7c3d1900-6a69-11e9-9686-6993b9d5f8ce.png
where: [image: image] https://user-images.githubusercontent.com/36746102/56899416-c1f9e180-6a69-11e9-8dcc-590fedaa9808.png and
key = startTime deactivatedPeriod = duration.
Then we run this: [image: image] https://user-images.githubusercontent.com/36746102/56899985-2b2e2480-6a6b-11e9-9394-6b0b78987235.png
[image: image] https://user-images.githubusercontent.com/36746102/56899944-0fc31980-6a6b-11e9-8550-d34ab3cf1910.png
Where:
_DataProcessor.GetOdfsCount() returns the jobs count
So the solver knows where not to put the tasks. There is another way that would help we achieve the mentioned behaviour? Or this would not change anything?
We need this functionallity to be able to use ORTools solver in our project.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223#issuecomment-487587340, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3NHFWYINSVCYH3A6I3PS34K3ANCNFSM4HIZUSHA .
That is a task interrupted by a break would resume as soon as the breaks stop ?
That's exactly what we need. Look at machine_0 in the image. See the purple (1 hour length) break interval after the first orange interval. That's a lunch break for example. So if a worker start a task in the first orange interval and leaves for lunch, it stops the task while lunch break and resume after the worker come back from the lunch time. The same happen when the task is longer than the day shift, it must resume in the next shift. That's the behaviour we want.
How can we do that?
Can you look at:
The last message in the thread is, IMO, the best option, It requires pre-processing, but it should work.
Above, you have the second option with split intervals.
Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le lun. 29 avr. 2019 à 17:19, gustavo-barros notifications@github.com a écrit :
That is a task interrupted by a break would resume as soon as the breaks stop ?
That's exactly what we need. Look at machine_0 in the image. See the purple (1 hour length) break interval after the first orange interval. That's a lunch break for example. So if a worker start a task in the first orange interval and leaves for lunch, it stops the task while lunch break and resume after the worker come back from the lunch time. That's the behaviour we want.
How can we do that?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223#issuecomment-487622611, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3IEY327OVAY6GCJ5JLPS4GZJANCNFSM4HIZUSHA .
Hey Laurent,
I tried to implement that idea with no success. I don't know if I grasp the idea correctly. This was my try:
Doing this I reached a no solution answer.
I didn't understand how it could split the tasks when there is a deactivated shift. How those dx parameters are set? Is during the solver running process?
I'm hitting a dead end here :(
I understand that "start" is all possible start states, "duration" is the range that durations can vary and "end" is the range where it can end, starting from 0 to 20 (max) in your case example; Then you create those boolean dx's variables.
and here seems you are setting constraints to set the booleans variables to true if they are attended, for example: if a task starts at any number between and including [0..1] U [14..15], d4 will be activated to true as says this constraint
and then it will set the task duration to 4 because d4 is true as
Is there any sense in what I told, or I completely miss the point? I need your help to understand this.
at the minimum, intervals should be non-overlapping. But this would not change the unsat part. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le lun. 29 avr. 2019 à 21:07, gustavo-barros notifications@github.com a écrit :
Hey Laurent,
I tried to implement that idea with no success. I don't know if I grasp the idea correctly. This was my try: [image: image] https://user-images.githubusercontent.com/36746102/56917475-f4b7d000-6a91-11e9-87df-d4371348eb5a.png
Doing this I reached a no solution answer.
I didn't understand how it could split the tasks when there is a deactivated shift. How those dx parameters are set? Is during the solver running process?
I'm hitting a dead end here :(
I understand that "start" is all possible start states, "duration" is the range that durations can vary and "end" is the range where it can end, starting from 0 to 20 (max) in your case example; Then you create those boolean dx's variables.
[image: image] https://user-images.githubusercontent.com/36746102/56919958-5713cf00-6a98-11e9-8cc0-9632d8aaaba0.png
and here seems you are setting constraints to set the booleans variables to true if they are attended, for example: if a task starts at any number between and including [0..1] U [14..15], d4 will be activated to true as says this constraint [image: image] https://user-images.githubusercontent.com/36746102/56919676-9e4d9000-6a97-11e9-92fe-81b2005d8660.png
and then it will set the task duration to 4 because d4 is true as [image: image] https://user-images.githubusercontent.com/36746102/56919802-e7054900-6a97-11e9-8e23-771585debadd.png
Is there any sense in what I told, or I completely miss the point? I need your help to understand this.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223#issuecomment-487704993, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3MAOIPXUZFQJA5JOT3PS5BPJANCNFSM4HIZUSHA .
Read the doc on NewEnumeratedIntVar, you need a flattened list on interval.
{1, 2, 3, 5, 7, 8, 9} is written as [1, 3, 5, 5, 7, 9]
Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le lun. 29 avr. 2019 à 21:11, Laurent Perron lperron@google.com a écrit :
at the minimum, intervals should be non-overlapping. But this would not change the unsat part. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le lun. 29 avr. 2019 à 21:07, gustavo-barros notifications@github.com a écrit :
Hey Laurent,
I tried to implement that idea with no success. I don't know if I grasp the idea correctly. This was my try: [image: image] https://user-images.githubusercontent.com/36746102/56917475-f4b7d000-6a91-11e9-87df-d4371348eb5a.png
Doing this I reached a no solution answer.
I didn't understand how it could split the tasks when there is a deactivated shift. How those dx parameters are set? Is during the solver running process?
I'm hitting a dead end here :(
I understand that "start" is all possible start states, "duration" is the range that durations can vary and "end" is the range where it can end, starting from 0 to 20 (max) in your case example; Then you create those boolean dx's variables.
[image: image] https://user-images.githubusercontent.com/36746102/56919958-5713cf00-6a98-11e9-8cc0-9632d8aaaba0.png
and here seems you are setting constraints to set the booleans variables to true if they are attended, for example: if a task starts at any number between and including [0..1] U [14..15], d4 will be activated to true as says this constraint [image: image] https://user-images.githubusercontent.com/36746102/56919676-9e4d9000-6a97-11e9-92fe-81b2005d8660.png
and then it will set the task duration to 4 because d4 is true as [image: image] https://user-images.githubusercontent.com/36746102/56919802-e7054900-6a97-11e9-8e23-771585debadd.png
Is there any sense in what I told, or I completely miss the point? I need your help to understand this.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223#issuecomment-487704993, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3MAOIPXUZFQJA5JOT3PS5BPJANCNFSM4HIZUSHA .
Hi @lperron,
We're trying to understand and implement what you're saying, and at the same time we're learning about the OR Tools and its solver functionality.
Is there any tool (ie: skype) that we can chat in 'real-time'? Maybe we can share our screen too.. I sent you a message on what I believe it's your skype's account.
We really need this functionality or the Google OR Tools will not fit our project needs..
at the minimum, intervals should be non-overlapping. But this would not change the unsat part. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00 Le lun. 29 avr. 2019 à 21:07, gustavo-barros notifications@github.com a écrit : … Hey Laurent, I tried to implement that idea with no success. I don't know if I grasp the idea correctly. This was my try: [image: image] https://user-images.githubusercontent.com/36746102/56917475-f4b7d000-6a91-11e9-87df-d4371348eb5a.png Doing this I reached a no solution answer. I didn't understand how it could split the tasks when there is a deactivated shift. How those dx parameters are set? Is during the solver running process? I'm hitting a dead end here :( I understand that "start" is all possible start states, "duration" is the range that durations can vary and "end" is the range where it can end, starting from 0 to 20 (max) in your case example; Then you create those boolean dx's variables. [image: image] https://user-images.githubusercontent.com/36746102/56919958-5713cf00-6a98-11e9-8cc0-9632d8aaaba0.png and here seems you are setting constraints to set the booleans variables to true if they are attended, for example: if a task starts at any number between and including [0..1] U [14..15], d4 will be activated to true as says this constraint [image: image] https://user-images.githubusercontent.com/36746102/56919676-9e4d9000-6a97-11e9-92fe-81b2005d8660.png and then it will set the task duration to 4 because d4 is true as [image: image] https://user-images.githubusercontent.com/36746102/56919802-e7054900-6a97-11e9-8e23-771585debadd.png Is there any sense in what I told, or I completely miss the point? I need your help to understand this. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#1223 (comment)>, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3MAOIPXUZFQJA5JOT3PS5BPJANCNFSM4HIZUSHA .
No, I have no time for chat, and I am on vacation.
Have you read:
https://github.com/google/or-tools/blob/master/ortools/sat/doc/integer_arithmetic.md
and more generally
https://github.com/google/or-tools/blob/master/ortools/sat/doc/README.md
(it seems github markdown rendering is down though).
Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le lun. 29 avr. 2019 à 22:04, KorpEduardoSikora notifications@github.com a écrit :
Hi @lperron https://github.com/lperron,
We're trying to understand and implement what you're saying, and at the same time we're learning about the OR Tools and its solver functionality.
Is there any tool (ie: skype) that we can chat in 'real-time'? Maybe we can share our screen too.. I sent you a message on what I believe it's your skype's account.
We really need this functionality or the Google OR Tools will not fit our project needs..
at the minimum, intervals should be non-overlapping. But this would not change the unsat part. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00 Le lun. 29 avr. 2019 à 21:07, gustavo-barros notifications@github.com a écrit : … <#m-161962866676888796> Hey Laurent, I tried to implement that idea with no success. I don't know if I grasp the idea correctly. This was my try: [image: image] https://user-images.githubusercontent.com/36746102/56917475-f4b7d000-6a91-11e9-87df-d4371348eb5a.png Doing this I reached a no solution answer. I didn't understand how it could split the tasks when there is a deactivated shift. How those dx parameters are set? Is during the solver running process? I'm hitting a dead end here :( I understand that "start" is all possible start states, "duration" is the range that durations can vary and "end" is the range where it can end, starting from 0 to 20 (max) in your case example; Then you create those boolean dx's variables. [image: image] https://user-images.githubusercontent.com/36746102/56919958-5713cf00-6a98-11e9-8cc0-9632d8aaaba0.png and here seems you are setting constraints to set the booleans variables to true if they are attended, for example: if a task starts at any number between and including [0..1] U [14..15], d4 will be activated to true as says this constraint [image: image] https://user-images.githubusercontent.com/36746102/56919676-9e4d9000-6a97-11e9-92fe-81b2005d8660.png and then it will set the task duration to 4 because d4 is true as [image: image] https://user-images.githubusercontent.com/36746102/56919802-e7054900-6a97-11e9-8e23-771585debadd.png Is there any sense in what I told, or I completely miss the point? I need your help to understand this. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#1223 (comment) https://github.com/google/or-tools/issues/1223#issuecomment-487704993>, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3MAOIPXUZFQJA5JOT3PS5BPJANCNFSM4HIZUSHA .
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223#issuecomment-487723264, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3IO5SF6EZ2X4MF5PV3PS5IGFANCNFSM4HIZUSHA .
Hi Laurent,
Sorry to bother you in your vacation. But this is very important to us, if you could help we will really appreciate it. I read all the examples you sent me, studied it and made several trials and errors here but something seems not to fit. There is something missing. Could you send me an example code related to our problem? So that it could enlight the path for us?
Our first valid shift is: [8..12] U [13..18]
If we could simply simulate the case in wich a task starts at 11, stops at 12 and resume at 13 would be enough for us to continue.
I have pushed
Which outputs
start=8 duration=3 across=0
start=9 duration=3 across=0
start=10 duration=3 across=0
start=11 duration=4 across=1
start=12 duration=4 across=1
start=14 duration=3 across=0
start=15 duration=3 across=0
It should be easy to adapt to other languages. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le mar. 30 avr. 2019 à 14:18, gustavo-barros notifications@github.com a écrit :
Hi Laurent,
Sorry to bother you in your vacation. But this is very important to us, if you could help we will really appreciate it. I read all the examples you sent me, studied it and made several trials and errors here but something seems not to fit. There is something missing. Could you send me an example code related to our problem? So that it could enlight the path for us?
Our first valid shift is: [8..12] U [13..18]
If we could simply simulate the case in wich a task starts at 11, stops at 12 and resume at 13 would be enough for us to continue.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223#issuecomment-487929313, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3IINLVPLYH4VQSMNPLPTA2IDANCNFSM4HIZUSHA .
Thank you Laurent,
Now I understand your logic. The problem is that my code have a different structure. It was based initially in this code: https://github.com/google/or-tools/blob/stable/examples/dotnet/JobshopSat.cs
So I tried to apply your logic:
[MY ORIGINAL CODE]
where odf = job and operation = task
[AFTER TRYING TO APPLY YOUR IDEA]
Of course my attempt is wrong, because my start is a IntVar not an NewEnumeratedIntVar. It found no solutions. But I think the answer is something like this.
When my code is working it writes to the console something like this:
Machine 5: Task O1J5M5D6 starts at 8
If starts at 8; duration = 6
I'm trying to do, following your idea, when starts at 11 for example it answers me:
Machine 5: Task O1J5M5D7 starts at 11
If starts at 11; duration = 7
Same thing, but with a different model data structure. How can I do this?
You can add start != break value if you want to the model.
You can also use AddLinearSumWithBounds() API (no need to create the tuple <start, 1>.
I do not understand your question. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le mar. 30 avr. 2019 à 20:34, gustavo-barros notifications@github.com a écrit :
Thank you Laurent,
Now I understand your logic. The problem is that my code have a different structure. It was based initially in this code:
https://github.com/google/or-tools/blob/stable/examples/dotnet/JobshopSat.cs
So I tried to apply your logic:
[MY ORIGINAL CODE]
where odf = job and operation = task [image: image] https://user-images.githubusercontent.com/36746102/56982513-e16f3800-6b57-11e9-8a23-4dc76e7f7668.png
[AFTER TRYING TO APPLY YOUR IDEA] [image: image] https://user-images.githubusercontent.com/36746102/56982540-f1871780-6b57-11e9-9048-c87a667e7908.png
Of course my attempt is wrong, because my start is a IntVar not an NewEnumeratedIntVar. It found no solutions. But I think the answer is something like this.
When my code is working it writes to the console something like this:
Machine 5: Task O1J5M5D6 starts at 8
If starts at 8; duration = 6
I'm trying to do, following your idea, when starts at 11 for example it answers me:
Machine 5: Task O1J5M5D7 starts at 11
If starts at 11; duration = 7
Same thing, but with a different model data structure. How can I do this?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223#issuecomment-488065009, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3I3NGZGPODNTPYVEE3PTCGKPANCNFSM4HIZUSHA .
Hi Laurent, I noticed that you added new features in the current version:
In the example you showed, the duration of the task could be 4 or 3 if is crossing or not. But how can I express thousands of tasks that can be expanded like that over the intervals?
For example, I have 4 different tasks with different durations. If they cross the interval they will be added up 1 unit of time, right. For example:
tasks durations:
if task_0 start at 12 AM it will end at 16 PM, hence duration = 4 if task_1 start at 12 AM it will end at 17 PM, hence duration = 5 if task_2 start at 11 AM it will end at 18 PM, hence duration = 7 if task_3 start at 10 AM it will end at 18 PM, hence duration = 8
So in summary:
It is possible to define a range like this?
duration = model.NewIntVar(3, 8, 'duration')
meaning that duration ranges of 3 to 8? Or should I do something like this?
duration = model.NewIntVarFromDomain( cp_model.Domain.FromIntervals([(3, 4), (4, 5), (6, 7), (7, 8)]), 'duration')
Now, if I have different intervals durations? For example, imagine the lunch break is at 13 PM to 14 PM and after 18 PM is the shutdown break interval. So it will span from 18 PM to 8 AM. And if a task with duration 4 start at 17 PM it should span until 8 AM, so duration is 18. With these NewIntVarFromDomain, can I express this case also?
Hey Laurent,
See the red box, "operation.Duration" is the value I want to change depending on a BoolVar. How can I make that?
So I was trying to apply your example in my code in such a way I could change the operation.Duration value depending on the change of the "duration" variable, as the image show below:
In this case "operation.Duration" would be 4 if "across" is true.
Is this possible? How can I do that?
Something like this:
Exactly. As a small optimization, you can write model.Add(duration == 3 + across); Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
De : gustavo-barros notifications@github.com Date : mer. 15 mai 2019 à 20:13 À : google/or-tools Cc : Laurent Perron, Mention
Something like this:
[image: image] https://user-images.githubusercontent.com/36746102/57798806-ed482600-7723-11e9-8c10-912abe031bda.png
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223?email_source=notifications&email_token=ACUPL3N2U5ORPWH4XLKQDATPVRHENA5CNFSM4HIZUSHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVPP3IA#issuecomment-492764576, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3OHNSJ3Y5QOOOWHMRTPVRHENANCNFSM4HIZUSHA .
I'm just trying some random values while I'm testing, I end up with this scenario:
I added a property of type "IntVar" called "ComputedDuration" to the "operation" class. Added a NewIntVar called "operationDuration" and added it to a list of IntVar. My expectation is, duration will be calculed depending on cross inside the solver and stored in my "operationDuration" variable and then inside the list, that I hope I can access after the calculation. But I can't, I get something like this:
In that I just have the domain (possible values) but not the duration itself. How can I retrieve this duration value after the calculation by the solver?
If there is a variable attached, you can ask the solver the value of that variable in the solution. You just need to store that variable.
Furthermore, when creating the duration variable, please try to restrict the bounds of the variable as much as possible (prefer [3--8] instead of [0--horizon]). Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
De : gustavo-barros notifications@github.com Date : mer. 15 mai 2019 à 21:51 À : google/or-tools Cc : Laurent Perron, Mention
I'm just trying some random values while I'm testing, I end up with this
scenario:
[image: image] https://user-images.githubusercontent.com/36746102/57804108-43bb6180-7730-11e9-9ca6-65bfd9fc1d09.png
I added a property of type "IntVar" called "ComputedDuration" to the "operation" class. Added a NewIntVar called "operationDuration" and added it to a list of IntVar. My expectation is, duration will be calculed depending on cross inside the solver and stored in my "operationDuration" variable and then inside the list, that I hope I can access after the calculation. But I can't, I get something like this:
[image: image] https://user-images.githubusercontent.com/36746102/57804369-e83da380-7730-11e9-83f7-9f9e5024c00b.png
[image: image] https://user-images.githubusercontent.com/36746102/57804387-f1c70b80-7730-11e9-818a-992d09116dd0.png
In that I just have the domain (possible values) but not the duration itself. How can I retrieve this duration value after the calculation by the solver?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223?email_source=notifications&email_token=ACUPL3MRO2RFKWGJEP5543DPVRSU5A5CNFSM4HIZUSHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVPYIKQ#issuecomment-492799018, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3OW5RSGUTMXJH5LF53PVRSU5ANCNFSM4HIZUSHA .
Ok Laurent, here are the major changes:
So I tried to ask the solver for the value here:
is that right? check the variable names changing. Where duration00 is the duration for the job 0 and task 0, and duration30 is the duration for the job 3 and task 0.
That
solver.Value(var)
should return me the duration value?
here is the scenario I'm trying to do, all tasks has lenght 3. So aproximately at 02:45-03:00 it should expand to +1 in lenght. Disregard the time scale, is not configured right.
I'm almost there, but something is still not right.
either
model.Add(Duration == data.duration + across)
or
model.Add(duration == data.Duration).OnlyEnforceIf(across.Not()) model.Add(duration == data.Duration + 1).OnlyEnforceIf(across)
Not a mix. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
De : gustavo-barros notifications@github.com Date : mer. 15 mai 2019 à 22:39 À : google/or-tools Cc : Laurent Perron, Mention
Ok Laurent, here are the major changes:
[image: image] https://user-images.githubusercontent.com/36746102/57807073-d19a4b00-7736-11e9-955f-9feeb24ee166.png
So I tried to ask the solver for the value here: [image: image] https://user-images.githubusercontent.com/36746102/57807184-09a18e00-7737-11e9-9419-bd09a26b74b0.png
is that right? check the variable names changing. Where duration00 is the duration for the job 0 and task 0, and duration30 is the duration for the job 3 and task 0. [image: image] https://user-images.githubusercontent.com/36746102/57807256-2fc72e00-7737-11e9-988a-546c564739ad.png [image: image] https://user-images.githubusercontent.com/36746102/57807310-4ec5c000-7737-11e9-83ec-e01daeddebde.png
That
solver.Value(var)
should return me the duration value?
here is the scenario I'm trying to do, all tasks has lenght 3. So aproximately at 02:45-03:00 it should expand to +1 in lenght. Disregard the time scale, is not configured right.
[image: image] https://user-images.githubusercontent.com/36746102/57807733-22f70a00-7738-11e9-893c-ce051fcf0dc6.png [image: image] https://user-images.githubusercontent.com/36746102/57807762-3013f900-7738-11e9-9907-a22b7413d7f7.png
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223?email_source=notifications&email_token=ACUPL3PB2DNBMGDTHNPLR63PVRYGXA5CNFSM4HIZUSHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVP4EEQ#issuecomment-492814866, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3JEZJMFEC37W4YPVEDPVRYGXANCNFSM4HIZUSHA .
Yes, I already fixed that. But it still returns 3 for all the data. For the machine_1 should be some 4's.
This give me a impression that maybe something related with the intervals?
I can provide more code if needed, any ideas? Really need your help. Seems the durations values are always setted to 3, that's the same as the original data.Duration. For some reason seems it doesn't setting the across state. But I have no sure :(
Yes, made some tests here. Across state are not being activated
It was in the code I wrote. So debug your code. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
De : gustavo-barros notifications@github.com Date : mer. 15 mai 2019 à 23:54 À : google/or-tools Cc : Laurent Perron, Mention
Yes, made some tests here. Cross state are not being activated
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223?email_source=notifications&email_token=ACUPL3OTFYTH3WNVNTNJBVLPVSBCBA5CNFSM4HIZUSHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVQBZKI#issuecomment-492838057, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3KPD3MHOSH44MQU3J3PVSBCBANCNFSM4HIZUSHA .
Ok. Can you explain for me how this two methods works or give me a direction where I can find reference about it?
Model.AddLinearExpressionInDomain()
Model.AddLinearConstraint()
I have sure it is something about the intervals that is not right, and then the "across" state is not becoming true.
A domain in a set of values build from values or integer intervals.
AddLinearConstraint(linear_expr, lb, ub) == AddLinearExpressionInDomain(linear_expr, new Domain(lb, ub))
The domain class is documented here:
https://github.com/google/or-tools/blob/master/ortools/util/sorted_interval_list.h#L57
Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
De : gustavo-barros notifications@github.com Date : jeu. 16 mai 2019 à 13:56 À : google/or-tools Cc : Laurent Perron, Mention
Ok. Can you explain for me how this two methods works or give me a
direction where I can find reference about it?
Model.AddLinearExpressionInDomain()
Model.AddLinearConstraint()
I have sure it is something about the intervals that is not right, and then the "across" state is not becoming true.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223?email_source=notifications&email_token=ACUPL3LYBPHYWKJRKLVW7FLPVVDWRA5CNFSM4HIZUSHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVRSLMA#issuecomment-493036976, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3JOJZYPIQCMSSYWRODPVVDWRANCNFSM4HIZUSHA .
this is the AddLinearConstraint() method that we are using?
https://github.com/google/or-tools/blob/v7.0/ortools/sat/pb_constraint.h#L150
No, this is an internal propagation code dedicated to pseudo-boolean constraints (that is linear constraints with Boolean variables). Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
De : gustavo-barros notifications@github.com Date : jeu. 16 mai 2019 à 14:24 À : google/or-tools Cc : Laurent Perron, Mention
this is the AddLinearConstraint() method that we are using?
https://github.com/google/or-tools/blob/v7.0/ortools/sat/pb_constraint.h#L150
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223?email_source=notifications&email_token=ACUPL3K6S4RGCEQ7ILNAJWTPVVG7PA5CNFSM4HIZUSHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVRUNEY#issuecomment-493045395, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3JGH22WJZ2GMXISQ73PVVG7PANCNFSM4HIZUSHA .
Hey Laurent, I was right about the domains, now it's working half the logic, thank you. I'm trying to adapt to my scenario, so I still have some doubts.
For example, I have this:
But I would like something like this: Of course I wouldn't declare the same variable twice. I need this OneTask to receive each one depending on the bool variables.
I'll explain you why I need that. Each machine has different inactive intervals during a day. So I'll try to loop over a array of NewBoolVar for each interval and a array of Durations. Something like this in the case of durations:
I need this because if a task hit the first interval it expands 1x4 blocks (1 hour in four 15 minutes blocks), BUT if a task hit the second interval that goes from 18:00 to 08:00 next day. It should expand 14x4 blocks. So how can I set my "OneTask" variable depending on my NewBoolVars ?
Here is the image of the first functional expansion:
Have you seen
? Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
De : gustavo-barros notifications@github.com Date : jeu. 16 mai 2019 à 20:03 À : google/or-tools Cc : Laurent Perron, Mention
Hey Laurent,
I was right about the domains, now it's working half the logic, thank you. I'm trying to adapt to my scenario, so I still have some doubts.
For example, I have this: [image: image] https://user-images.githubusercontent.com/36746102/57874880-f4386c80-77e7-11e9-8118-32f41d2d47ff.png
But I would like something like this: [image: image] https://user-images.githubusercontent.com/36746102/57874979-2c3faf80-77e8-11e9-9da7-843564c3f118.png Of course I wouldn't declare the same variable twice. I need this OneTask to receive each one depending on the bool variables.
I'll explain you why I need that. Each machine has different inactive intervals during a day. So I'll try to loop over a array of NewBoolVar for each interval and a array of Durations. Something like this in the case of durations: [image: image] https://user-images.githubusercontent.com/36746102/57876375-8b52f380-77eb-11e9-86a9-d0e680bc6290.png
I need this because if a task hit the first interval it expands 1x4 blocks (1 hour in four 15 minutes blocks), BUT if a task hit the second interval that goes from 18:00 to 08:00 next day. It should expand 14x4 blocks. So how can I set my "OneTask" variable depending on my NewBoolVars ?
Here is the image of the first functional expansion: [image: image] https://user-images.githubusercontent.com/36746102/57875784-17641b80-77ea-11e9-9b19-bc4ca21fde21.png
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223?email_source=notifications&email_token=ACUPL3O5N5XR4DA6RCQIFS3PVWOVRA5CNFSM4HIZUSHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVSTLTA#issuecomment-493172172, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3PFO4MRS3AW6UZ3R5TPVWOVRANCNFSM4HIZUSHA .
There is a way to do set operations like, union, intersect, exclude using Domains? Would be very good if possible.
For example if we have:
var availableDomain = Domain.FromIntervals(new[]
{
new long[] {8, 12},
new long[] {13, 18},
new long[] {27, 31},
new long[] {32, 137}
});
var crossingDomain1 = Domain.FromIntervals(new[]
{
new long[] {11, 12}
});
var crossingDomain2 = Domain.FromIntervals(new[]
{
new long[] {16,17}
});
notCrossingDomain = availableDomain.Exclude(crossingDomain1);
notCrossingDomain.Exclude(crossingDomain2);
// SO WE HAVE AT END
notCrossingDomain =
{
{8, 10},
{13, 15},
{18, 27},
{32, 137}
}
Or something like that
It is possible in C++, I did not wrap all functions in C#. I will do it for 7.2.
Here is the API in C++
https://github.com/google/or-tools/blob/f3fd201e68cf75b7720ff5c3cadc599a1d02b54b/ortools/util/sorted_interval_list.h#L65 Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
De : gustavo-barros notifications@github.com Date : jeu. 16 mai 2019 à 21:56 À : google/or-tools Cc : Laurent Perron, Mention
For example if we have:
var availableDomain = Domain.FromIntervals(new[] { new long[] {8, 12}, new long[] {13, 18}, new long[] {27, 31}, new long[] {32, 137} });
var crossingDomain1 = Domain.FromIntervals(new[] { new long[] {11, 12} }); var crossingDomain2 = Domain.FromIntervals(new[] { new long[] {16,17} }); notCrossingDomain = availableDomain.Exclude(crossingDomain1); notCrossingDomain.Exclude(crossingDomain2);
// SO WE HAVE AT END notCrossingDomain = { {8, 10}, {13, 15}, {18, 27}, {32, 137} }
Or something like that
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223?email_source=notifications&email_token=ACUPL3IAV6OSKJGN6CU4MWDPVW36VA5CNFSM4HIZUSHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVS4SIQ#issuecomment-493209890, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3PENMXUIGKA5GDFWBDPVW36VANCNFSM4HIZUSHA .
Hey Laurent, I'm almost done with this feature. But I still have some problems. I'm trying to write a sequencial code that simulates a loop with 2 iterations (can be more later, if it works). So I'm doing the things in double to attempt to set these durations variations through different intervals of different lenght ( in this case 2 different intervals). For each block I calculate the crossing and non-crossing domains because it depends on the block lenght.
The first run I setted just the first interval, and it worked as you can see below:
In the second run I setted the second interval, and it also worked as you can see below:
In the third run I tryed to bring all together and setted the first and second intervals, this time things runned wild (don't know why yet) as you can see:
Any ideas?
How the domains were calculated:
Maybe it should not have intersections between the notCrossings?
I would suggest the following
write a loop for the start
accumulate the duration of the task, skip breaks, and record end and total duration
bucketize these
duration = 2 on {...} duration = 3 on {...}
use this in the Domain.FromValues() Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le ven. 17 mai 2019 à 17:05, gustavo-barros notifications@github.com a écrit :
How the domains were calculated:
[image: image] https://user-images.githubusercontent.com/36746102/57937272-f6f49980-789b-11e9-9244-716610bd224c.png
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223?email_source=notifications&email_token=ACUPL3MJRQ7C473QZEZCXRLPV3CUDA5CNFSM4HIZUSHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVVALRY#issuecomment-493487559, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3N6ZTZH42JTZ7PIBZ3PV3CUDANCNFSM4HIZUSHA .
Sorry, I didn't understand how to apply what you said in my code.
Hey Laurent,
Good news! I was able to solve the problem. Expansions for different intervals lenghts. Give it a look:
But now I'm having a collateral problem. I don't know why the tasks are preferably being put at the right of the available intervals in all cases when its possible. It should be put preferably at left, there is no sense to let the machines idles like that.
Any idea?
short answer, because nobody tells the solver to do so.
long answer: solve the problem once. Store the optimal makespan. Change the model to fix the makespan and minimize the sum of start times of tasks resolve the problem. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le lun. 20 mai 2019 à 16:41, gustavo-barros notifications@github.com a écrit :
Hey Laurent,
Good news! I was able to solve the problem. Expansions for different intervals lenghts. Give it a look:
[image: image] https://user-images.githubusercontent.com/36746102/58029578-4385e200-7af3-11e9-904b-d580bc1e2ff9.png
But now I'm having a collateral problem. I don't know why the tasks are being preferably being put at the right of the available intervals in all cases when its possible. It should be put preferably at left, there is no sense to let the machines idles like that.
[image: image] https://user-images.githubusercontent.com/36746102/58029174-7380b580-7af2-11e9-9470-4a7654340126.png
[image: image] https://user-images.githubusercontent.com/36746102/58029308-a9be3500-7af2-11e9-84d2-e1818d592ec8.png
[image: image] https://user-images.githubusercontent.com/36746102/58029372-c9edf400-7af2-11e9-97e9-f670c4ab4dc2.png
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223?email_source=notifications&email_token=ACUPL3K56RGEIZUZN6B2AQTPWK2DFA5CNFSM4HIZUSHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVZBQDY#issuecomment-494016527, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3PXRHM4GBM4UTJ2NLLPWK2DFANCNFSM4HIZUSHA .
Hmmm I see.
How can I do that storage procedure following a remodeling process? You have any example for me to see?
After the first Solve(), calling Minimize() again will overwrite the previous objective. Then you can add a constraint on the makespan as you built the model.
To speed the second solve(), you can hint the previous solution. But there are no API currently for that. Although the code will be small. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le lun. 20 mai 2019 à 16:50, gustavo-barros notifications@github.com a écrit :
Hmmm I see.
How can I do that storage procedure following a remodeling process? You have any example for me to see?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223?email_source=notifications&email_token=ACUPL3JUPWA3OOFL5O3GLZ3PWK3BPA5CNFSM4HIZUSHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVZCLMA#issuecomment-494020016, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3O3HAXLI36VFSGWFATPWK3BPANCNFSM4HIZUSHA .
Something like this:
In wich:
Then solve it with the "allEndings":
If solved as optimal set the allStarts as minimize objective:
Then solve it again?
You think it is possible to do something like this, without running the solver again?
In this case I have the domain of all available intervals. So if in some way I could tell the solver that the task start should be always bigger or equal to the start of the available interval. But preferably equal or the closest possible. Maybe then running the solver again wouldn't be necessary.
Hey Laurent,
Have you any material explaining how these works?
DecisionStrategyProto.Types.VariableSelectionStrategy DecisionStrategyProto.Types.DomainReductionStrategy
There are some options inside those classes like for example "ChooseFirst". I would like to know how each of these works, what it is for, etc.
Also you have something about these:
Model.AddMaxEquality(); Model.Minimize();
And others functions similar to those?
Everything is documented in non C# languages. C# doc tags are just too painful to use.
https://github.com/google/or-tools/blob/stable/ortools/sat/cp_model.proto
or
https://github.com/google/or-tools/blob/stable/ortools/sat/python/cp_model.py https://github.com/google/or-tools/blob/stable/ortools/sat/cp_model.proto
For the decision part, the names are quite explicit
Choose first variable, choose variable with min size... select min value...
AddMaxEquality(target, IntVar[] array) => target == max(array) Minimize(linear_expr) is the objective to minimize.
Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le mar. 21 mai 2019 à 12:53, gustavo-barros notifications@github.com a écrit :
Hey Laurent,
Have you any material explaining how these works?
DecisionStrategyProto.Types.VariableSelectionStrategy DecisionStrategyProto.Types.DomainReductionStrategy
There are some options inside those classes like for example "ChooseFirst". I would like to know how each of these works, what it is for, etc.
Also you have something about these:
Model.AddMaxEquality(); Model.Minimize();
And others functions similar to those?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1223?email_source=notifications&email_token=ACUPL3KP4M5CK22YO3FT33TPWPICJA5CNFSM4HIZUSHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODV3Q6LA#issuecomment-494341932, or mute the thread https://github.com/notifications/unsubscribe-auth/ACUPL3LVLIC6NAEZ2DMU5I3PWPICJANCNFSM4HIZUSHA .
Hi,
I'm trying to solve a jobShop like problem for a factory floor operations scheduling. I'm using CPSolver.
The problem is that I have a factory Plant that works on a set of predefined work shifts. Each machine can have it's own work shift for each day of the calendar. So I configure the model to distribute the tasks only in the allowed time period.
The difficult part happens when there is a task length that exceeds the length of the available work shift time. The solver simply move the entire task to the next day shift or next allowed time space. So I was wondering, is there a way to make the solver split the task between two work shifts?
See the image below, the orange blocks are the allowed ones defined in the machine shift for that specific day. The purple ones are not allowed to be used because is the time that the factory shutdown. The blue block (30002/1) for example is a block that I wanted to be splitted, because it has no dependencies and there is a free space at it's left as shown in the image:
After this procedure, the result should be something like this image below, and this behaviour should be applied to each task that fits in this case and are longer than the available space: