Combined multiple problem in Scheduling #1252
Replies: 15 comments
-
You need to map hours to integer values.
there are 168 hours in a week.
So for one week, the horizon is 168.
To force one task to be done on Monday, restrict the end date to be before
24 (assuming Monday is the first day of the week).
For the transit, look at example
https://github.com/google/or-tools/blob/master/examples/python/jobshop_ft06_distance_sat.py
Laurent Perron | Operations Research | [email protected] | (33) 1 42 68 53
00
*De : *☂ Giang Strider ☂ <[email protected]>
*Date : *mar. 7 mai 2019 à 06:44
*À : *google/or-tools
*Cc : *Subscribed
Hi, I went through many examples of the scheduling problem, but it seems my
… problem combines many complicated things, and so hard for the newbie like
me to do it. If anyone can help or give some instruction to do it, I'm very
appreciated.
I have the following problem:
The main goal is scheduling workers to do the tasks in one week. (Monday
-> Friday, 6AM to 6PM per day)
1.
There is a list of tasks and workers.
Workers need to assigned to do the tasks. Each task has a deadline
date to do, a duration (unit time to be done)
2.
Each worker has there owned blocking time (to do a meeting for
example) in a week, and their blocking time needs to be scheduled an exact
date in the week. (It's possible to fix this to start in 6AM before to do
another task.). Each blocking time also a duration (unit time to be done).
3.
Each worker has their own skills. Each task required skill for a
worker to done the task.
4.
each task has own location. There is a matrix of traveling time
between the tasks:
like
A | B
A 0 | 2
B 2 | 0
(A,B is the task)
(Each number is unit of time)
Constraint:
1. Tasks and Blocking time not overlap.
2. Each task only assigned to 1 worker.
3. Task's required skill == worker skills.
Objective:
Minize traveling time of workers.
The way I modeling is:
1. Create a list of NewIntervalVar of worker's blocking_time.
2. Create a list of NewOptionalIntervalVar of tasks. (Since tasks can
happen or not).
3. Add Nonoverlap of [NewIntervalVar_blockingtime,
NewOptionalIntervalVar_tasks].
My problem is:
1. I don't know how to link between the weekday ["Monday", "Tuesday",
"Wednesday", "Thursday", "Friday"] within the tasks and blocking_times.
(Mean which task assigned to which weekday).
2. How to add constraint like if the tasks assigned to Monday (for
example), if assigned one more task has a long duration, so the worker to
need work until 7PM, So this task need shift to Tuesday.
3. How to compute the objective (traveling time) to minize.
Feel free to comment or modify my model since I'm not sure it corrects.
Thanks very much.
My example code:
all_tasks = []for block in data['blocked_times']:
start_blocking = model.NewIntVar(0, horizon, 'start_block_%s_%s' % (block['worker_id'], block['blocked_id']))
end_blocking = model.NewIntVar(0, horizon, 'end_block_%s_%s' % (block['worker_id'], block['blocked_id']))
duration = block['activity_duration']
interval_blocking = model.NewIntervalVar(start_blocking, duration, end_blocking, 'interval_block_%s_%s' % (block['worker_id'], block['blocked_id']))
all_tasks.append(interval_blocking)
for task in data['tasks']:
start_task = model.NewIntVar(0, horizon, 'start_task_%s' % (task['task_id']))
end_task = model.NewIntVar(0, horizon, 'end_task_%s' % (task['task_id']))
duration = block['activity_duration']
presence_task = model.NewBoolVar('presence_%s' % task['task_id'])
interval_task = model.NewOptionalIntervalVar(
start_task, duration, end_task, presence_task, 'interval_task_%s' % task['task_id']
)
all_tasks.append(interval_task)
model.AddNoOverlap(all_tasks)
—
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/1252>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACUPL3L7YSPAWPYI3K2Q2ZTPUECMLANCNFSM4HLFJYLQ>
.
|
Beta Was this translation helpful? Give feedback.
-
Hi @lperron , thanks for your reply. I'm can model work for the basic case now. |
Beta Was this translation helpful? Give feedback.
-
sum(boolvars) == 1 ?
Laurent Perron | Operations Research | [email protected] | (33) 1 42 68 53
00
*De : *☂ Giang Strider ☂ <[email protected]>
*Date : *lun. 13 mai 2019 à 09:25
*À : *google/or-tools
*Cc : *Laurent Perron, Mention
Hi @lperron <https://github.com/lperron> , thanks for your reply. I'm can
… model work for the basic case now.
I'm stuck at constraint how to for 1 task is executed by only one worker.
Since the list of tasks is represented by the list of OptionalIntervalVar,
with literal BoolVar controlled it.
I don't know how to use BoolVar to model this constraint.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<https://github.com/google/or-tools/issues/1252#issuecomment-491706370>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACUPL3NI2UQZAEXXW3NGGNLPVEJW7ANCNFSM4HLFJYLQ>
.
|
Beta Was this translation helpful? Give feedback.
-
Thanks @lperron , I use same methods but the wrong way. It's ok now. I'm wondering how to identify the distance between two jobs. For example in Is there any way to access the metadata of the job which defined before? Like |
Beta Was this translation helpful? Give feedback.
-
Because in this toy problem, distance(j1, j2) == abs(j2 - j1).
Please replace with any custom distance.
Laurent Perron | Operations Research | [email protected] | (33) 1 42 68 53
00
*De : *☂ Giang Strider ☂ <[email protected]>
*Date : *lun. 13 mai 2019 à 11:07
*À : *google/or-tools
*Cc : *Laurent Perron, Mention
Thanks @lperron <https://github.com/lperron> , I use same methods but the
… wrong way. It's ok now.
For the transit, at this line:
https://github.com/google/or-tools/blob/master/examples/python/jobshop_ft06_distance_sat.py#L104
I'm wondering how to identify the distance between two jobs. For example
in jobshop_ft06_distance_sat,
https://github.com/google/or-tools/blob/master/examples/python/jobshop_ft06_distance_sat.py#L34
How j2 - j1 can identify as distance?
How can I get input my custom data?
Is there any way to access the metadata of the job which defined before?
Like j1.name? (From name I can extract the ID and mapping to my custom
data)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<https://github.com/google/or-tools/issues/1252#issuecomment-491740771>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACUPL3OHPE62FUPGHT4S653PVEVWVANCNFSM4HLFJYLQ>
.
|
Beta Was this translation helpful? Give feedback.
-
About metadata, I use the named tuples for that.
Laurent Perron | Operations Research | [email protected] | (33) 1 42 68 53
00
*De : *Laurent Perron <[email protected]>
*Date : *lun. 13 mai 2019 à 11:53
*À : *google/or-tools
*Cc : *google/or-tools, Mention
Because in this toy problem, distance(j1, j2) == abs(j2 - j1).
… Please replace with any custom distance.
Laurent Perron | Operations Research | ***@***.*** | (33) 1 42 68
53 00
*De : *☂ Giang Strider ☂ ***@***.***>
*Date : *lun. 13 mai 2019 à 11:07
*À : *google/or-tools
*Cc : *Laurent Perron, Mention
Thanks @lperron <https://github.com/lperron> , I use same methods but the
> wrong way. It's ok now.
> For the transit, at this line:
>
> https://github.com/google/or-tools/blob/master/examples/python/jobshop_ft06_distance_sat.py#L104
>
> I'm wondering how to identify the distance between two jobs. For example
> in jobshop_ft06_distance_sat,
> https://github.com/google/or-tools/blob/master/examples/python/jobshop_ft06_distance_sat.py#L34
> How j2 - j1 can identify as distance?
> How can I get input my custom data?
>
> Is there any way to access the metadata of the job which defined before?
> Like j1.name? (From name I can extract the ID and mapping to my custom
> data)
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/google/or-tools/issues/1252#issuecomment-491740771>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/ACUPL3OHPE62FUPGHT4S653PVEVWVANCNFSM4HLFJYLQ>
> .
>
|
Beta Was this translation helpful? Give feedback.
-
Thanks for your help @lperron . I able to make transit work. I'm thinking modify somewhere in this for loop https://github.com/google/or-tools/blob/master/examples/python/jobshop_ft06_distance_sat.py#L88 |
Beta Was this translation helpful? Give feedback.
-
Same thing, you have one boolean from the dummy node to each task.
You can add a enforced linear equation using this boolean.
Laurent Perron | Operations Research | [email protected] | (33) 1 42 68 53
00
*De : *☂ Giang Strider ☂ <[email protected]>
*Date : *lun. 13 mai 2019 à 15:42
*À : *google/or-tools
*Cc : *Laurent Perron, Mention
Thanks for your help @lperron <https://github.com/lperron> . I able to make
… transit work.
just a little extend about the transit,
The jobshop distance example works for the transit between tasks, but how
about transit between from the beginning to the task location?
From start of the day, there is a distance moving from the worker's home
to the task's location = X
So for example, the task start of interval var is 24 (beginning of
Tuesday), I would like to add moving time, so the start will be: start =
start + X.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<https://github.com/google/or-tools/issues/1252?email_source=notifications&email_token=ACUPL3PGJP6MY4RNVSSQSC3PVFV47A5CNFSM4HLFJYL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVILBXA#issuecomment-491827420>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACUPL3MF7VX3DJ5VRJAVQQLPVFV47ANCNFSM4HLFJYLQ>
.
|
Beta Was this translation helpful? Give feedback.
-
Thanks a lot! @lperron For example, If the task starts at 47 (Tuesday) and has a duration = 3. Seconds, there is 2 objective I would like to Minimize:
Thanks |
Beta Was this translation helpful? Give feedback.
-
You need to restrict the start time to only valid values. For this, use a
special domain for the start var.
Please note that the API to use this has changed with or-tools 7.1.
Laurent Perron | Operations Research | [email protected] | (33) 1 42 68 53
00
*De : *☂ Giang Strider ☂ <[email protected]>
*Date : *mar. 14 mai 2019 à 05:36
*À : *google/or-tools
*Cc : *Laurent Perron, Mention
Thanks a lot! @lperron <https://github.com/lperron>
… I'm struggling with next constraint.
For example, If the task starts at 47 (Tuesday) and has a duration = 3.
This task will end at 50, it's mean span to Wednesday.
How can I prevent this, moving this task to another time slot if the task
span from today to the nextday?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<https://github.com/google/or-tools/issues/1252?email_source=notifications&email_token=ACUPL3OVHPSEBLMZAQNDJKDPVIXUXA5CNFSM4HLFJYL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVKFMFY#issuecomment-492066327>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACUPL3KQI23CFDWQXK7JIHTPVIXUXANCNFSM4HLFJYLQ>
.
|
Beta Was this translation helpful? Give feedback.
-
Hi @lperron , I've back from sick, thanks for your help.
As I understand, For example, we have 2 workers and 3 tasks. Here is my code arcs = []
for idx_i in range(len(task_intervals)):
# dummy node
start_literal = model.NewBoolVar('%i_first_job' % idx_i)
end_literal = model.NewBoolVar('%i_last_job' % idx_i)
arcs.append([0, idx_i + 1, start_literal])
arcs.append([idx_i + 1, 0, end_literal])
i_point = idx_i
# Worker's home to task's location model
worker_point = workers[idx_i]
worker_to_location_distance = toy_distance_1
model.Add(starts_assignment[idx_i] >= worker_to_location_distance).OnlyEnforceIf(start_literal)
for idx_j in range(len(task_intervals)):
if idx_i == idx_j:
continue
literal = model.NewBoolVar('%i_follows_%i' % (idx_j, idx_i))
arcs.append([idx_i + 1, idx_j + 1, literal])
j_point = idx_j
model.Add(starts_tasks[idx_j] >= ends_tasks[idx_i] + toy_distance_2).OnlyEnforceIf(literal)
model.AddCircuit(arcs) |
Beta Was this translation helpful? Give feedback.
-
I would imagine creating a dummy node and each night break, and adding it
in the circuit.
I think you need 1 circuit per person.
Laurent Perron | Operations Research | [email protected] | (33) 1 42 68 53
00
*De : *☂ Giang Strider ☂ <[email protected]>
*Date : *sam. 18 mai 2019 à 17:20
*À : *google/or-tools
*Cc : *Laurent Perron, Mention
Hi @lperron <https://github.com/lperron> , I've back from sick, thanks for
… your help.
After experienced a few days, I found my model not correct for this
problem.
just a little extend about the transit,
The jobshop distance example works for the transit between tasks, but how
about transit between from the beginning to the task location?
From start of the day, there is a distance moving from the worker's home
to the task's location = X
So for example, the task start of interval var is 24 (beginning of
Tuesday), I would like to add moving time, so the start will be: start =
start + X.
Same thing, you have one boolean from the dummy node to each task. You can
add a enforced linear equation using this boolean. Laurent Perron |
Operations Research | ***@***.*** | (33) 1 42 68 53 00
… <#m_7971818429051772032_>
As I understand, For example, we have 2 workers and 3 tasks.
That's mean for each worker, we create 3 start_literal for 3 tasks, and
only one start_literal=True.
In my problem, for each Monday, Tuesday ... til Friday, look like each day
need 1 start_literal=True (5 start_literal = True for the whole week),
because each day, the worker will move from home to the task's location.
Is there any way or example to model this?
Here is my code
arcs = []
for idx_i in range(len(task_intervals)):
# dummy node
start_literal = model.NewBoolVar('%i_first_job' % idx_i)
end_literal = model.NewBoolVar('%i_last_job' % idx_i)
arcs.append([0, idx_i + 1, start_literal])
arcs.append([idx_i + 1, 0, end_literal])
i_point = idx_i
for idx_j in range(len(task_intervals)):
if idx_i == idx_j:
continue
literal = model.NewBoolVar('%i_follows_%i' % (idx_j, idx_i))
arcs.append([idx_i + 1, idx_j + 1, literal])
j_point = idx_j
model.Add(starts_tasks[idx_j] >= ends_tasks[idx_i] + toy_distance).OnlyEnforceIf(literal)
model.AddCircuit(arcs)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<https://github.com/google/or-tools/issues/1252?email_source=notifications&email_token=ACUPL3OZJ2WMRY5T73POE2DPWANEHA5CNFSM4HLFJYL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVWQQUQ#issuecomment-493684818>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACUPL3JHMUW6WN4V7IQATGDPWANEHANCNFSM4HLFJYLQ>
.
|
Beta Was this translation helpful? Give feedback.
-
Hi @lperron , can you more clarify, how I can define a night break. |
Beta Was this translation helpful? Give feedback.
-
You will need 1 circuit per worker. 5 extra night nodes per circuit.
Then 1 constraint per day shift that says 1 shift is done by exactly 1
worker.
Le lun. 20 mai 2019 à 11:30, ☂ Giang Strider ☂ <[email protected]> a
écrit :
… Hi @lperron <https://github.com/lperron> , can you more clarify, how I
can define a night break.
And with N workers, it's mean creating N * 5 (Monday..Friday) dummy node
per worker, and add it in the circuit? (So N times add to the circuit?)
Am I right?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<https://github.com/google/or-tools/issues/1252?email_source=notifications&email_token=ACUPL3JQDIXF4IZIHNMGCYDPWJVR5A5CNFSM4HLFJYL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVYHM3Y#issuecomment-493909615>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACUPL3NP7GEOKZCQDK7QAN3PWJVR5ANCNFSM4HLFJYLQ>
.
|
Beta Was this translation helpful? Give feedback.
-
Sorry @lperron , I still stuck with this. weekdays = range(0,5)
workers = range(0,3)
tasks_starts = [1_start, ..., 5_start]
tasks_intervals = [1_interval, ..., 5_interval]
tasks_ends = [1_end, ..., 5_end]
for worker in workers:
arcs = []
for t1 in range(len(tasks_intervals)):
start_lit = model.NewBoolVar('%i_start_node' % (t1))
arcs.append([0, t1 + 1, start_lit])
w_to_t1_distance = toy_distance(w, t1)
# 5 extra night nodes
for w in weekdays:
night_break_node_literal = model.NewBoolVar('%i_night_break_%i' % (w, t1))
# Add night break node
arcs.append([t1 + 1, 0, night_break_node_literal])
task_start_bound, task_end_bound = toy_bound(w) # (12,24) is bound limit of w=1(Tuesday) for example
model.Add(tasks_starts[t1] >= task_start_bound + inspector_to_i_distance).OnlyEnforceIf(start_lit)
model.Add(tasks_ends[t1] <= task_end_bound)
for t2 in range(len(tasks_intervals)):
if t1 == t2:
continue
lit = model.NewBoolVar('%i_follows_%i' % (t1, t2))
arcs.append([t1 + 1, t2 + 1, lit])
t1_to_t2_distance = toy_distance(t1, t2)
model.Add(tasks_starts[t2] >= tasks_ends[t1] + t1_to_t2_distance).OnlyEnforceIf(lit)
model.AddCircuit(arcs) |
Beta Was this translation helpful? Give feedback.
-
Hi, I went through many examples of the scheduling problem, but it seems my problem combines many complicated things, and so hard for the newbie like me to do it. If anyone can help or give some suggestion to do it, I'm very appreciated.
I have the following problem:
The main goal is scheduling workers to do the tasks in one week. (Monday -> Friday, 6AM to 6PM per day)
There is a list of tasks and workers.
Workers need to assigned to do the tasks. Each task has a deadline date to do, a duration (unit time to be done)
Each worker has there owned blocking time (to do a meeting for example) in a week, and their blocking time needs to be scheduled an exact date in the week. (It's possible to fix this to start in 6AM before to do another task.). Each blocking time also a duration (unit time to be done).
Each worker has their own skills. Each task required skill for a worker to done the task.
each task has own location. There is a matrix of traveling time between the tasks:
like
A | B
A 0 | 2
B 2 | 0
(A,B is the task)
(Each number is unit of time)
Constraint:
Objective:
Minimize traveling time of workers.
The way I modeling is:
My problem is:
Feel free to comment or modify my model since I'm not sure it corrects. Thanks very much.
My example code:
Beta Was this translation helpful? Give feedback.
All reactions