polish CP-SAT Python jobshop examples

This commit is contained in:
Laurent Perron
2018-12-30 10:26:39 +01:00
parent cca2619276
commit 65eb9e09c3
2 changed files with 24 additions and 26 deletions

View File

@@ -24,15 +24,17 @@ def main():
"""Solves a jobshop with maintenance on one machine."""
model = cp_model.CpModel()
jobs = [[(5, 0, 20)], [(10, 1, 20)], [(6, 3, 60)], [(10, 2, 100)],
[(50, 4, 500)], [(12, 4, 50)], [(3, 0, 300)], [(5, 4, 500)],
[(3, 3, 300)], [(5, 4, 500)]]
jobs_data = [ # task = (machine_id, processing_time).
[(0, 3), (1, 2), (2, 2)], # Job0
[(0, 2), (2, 1), (1, 4)], # Job1
[(1, 4), (2, 3)] # Job2
]
machines_count = max(task[1] for job in jobs for task in job) + 1
machines_count = 1 + max(task[0] for job in jobs_data for task in job)
all_machines = range(machines_count)
# Computes horizon dynamically as the sum of all durations.
horizon = sum(task[0] for job in jobs for task in job)
horizon = sum(task[1] for job in jobs_data for task in job)
# Named tuple to store information about created variables.
task_type = collections.namedtuple('Task', 'start end interval')
@@ -44,31 +46,26 @@ def main():
all_tasks = {}
machine_to_intervals = collections.defaultdict(list)
for j, job in enumerate(jobs):
for j, job in enumerate(jobs_data):
for t, task in enumerate(job):
suffix = '_%i_%i' % (j, t)
start_var = model.NewIntVar(0, horizon, 'start' + suffix)
end_var = model.NewIntVar(0, horizon, 'end' + suffix)
interval_var = model.NewIntervalVar(start_var, task[0], end_var,
interval_var = model.NewIntervalVar(start_var, task[1], end_var,
'interval' + suffix)
all_tasks[j, t] = task_type(
start=start_var, end=end_var, interval=interval_var)
machine_to_intervals[task[1]].append(interval_var)
machine_to_intervals[task[0]].append(interval_var)
# Add maintenance interval.
machine_to_intervals[0].append(model.NewIntervalVar(6, 4, 10, 'weekend_0'))
machine_to_intervals[0].append(model.NewIntervalVar(4, 4, 8, 'weekend_0'))
# Create disjuctive constraints.
for m in all_machines:
model.AddNoOverlap(machine_to_intervals[m])
# Add deadlines on tasks.
for j, job in enumerate(jobs):
for t, task in enumerate(job):
model.Add(all_tasks[j, t].end <= task[2])
# Precedences inside a job.
for j, job in enumerate(jobs):
for j, job in enumerate(jobs_data):
for t in range(len(job) - 1):
model.Add(all_tasks[j, t + 1].start >= all_tasks[j, t].end)
@@ -76,7 +73,7 @@ def main():
obj_var = model.NewIntVar(0, horizon, 'makespan')
model.AddMaxEquality(
obj_var,
[all_tasks[j, len(job) - 1].end for j, job in enumerate(jobs)])
[all_tasks[j, len(job) - 1].end for j, job in enumerate(jobs_data)])
model.Minimize(obj_var)
# Solve model.
@@ -90,15 +87,15 @@ def main():
# Create one list of assigned tasks per machine.
assigned_jobs = collections.defaultdict(list)
for j, job in enumerate(jobs):
for j, job in enumerate(jobs_data):
for t, task in enumerate(job):
machine = task[1]
machine = task[0]
assigned_jobs[machine].append(
assigned_task_type(
start=solver.Value(all_tasks[j, t].start),
job=j,
index=t,
duration=task[0]))
duration=task[1]))
# Create per machine output lines.
sol_line = ''

View File

@@ -112,32 +112,33 @@ def MinimalJobshopSat():
job=job,
index=task_id))
disp_col_width = 10
# Create per machine output lines.
sol_line = ''
sol_line_tasks = ''
print('Optimal Schedule', '\n')
for machine in all_machines:
# Sort by starting time.
assigned_jobs[machine].sort()
sol_line += 'Machine ' + str(machine) + ': '
sol_line_tasks += 'Machine ' + str(machine) + ': '
sol_line += ' - machine ' + str(machine) + ': '
sol_line_tasks += ' - machine ' + str(machine) + ': '
for assigned_task in assigned_jobs[machine]:
name = 'job_%i_%i' % (assigned_task.job, assigned_task.index)
# Add spaces to output to align columns.
sol_line_tasks += name + ' ' * (disp_col_width - len(name))
sol_line_tasks += '%10s' % name
start = assigned_task.start
duration = jobs_data[assigned_task.job][assigned_task.index][1]
sol_tmp = '[%i,%i]' % (start, start + duration)
# Add spaces to output to align columns.
sol_line += sol_tmp + ' ' * (disp_col_width - len(sol_tmp))
sol_line += '%10s' % sol_tmp
sol_line += '\n'
sol_line_tasks += '\n'
# Finally print the solution found.
print('Optimal Schedule', '\n')
print(sol_line_tasks)
print('Task Time Intervals\n')
print(sol_line)