diff --git a/examples/python/scheduling_with_transitions_sat.py b/examples/python/scheduling_with_transitions_sat.py index 6c91f31d8b..29fdef10b0 100644 --- a/examples/python/scheduling_with_transitions_sat.py +++ b/examples/python/scheduling_with_transitions_sat.py @@ -33,11 +33,56 @@ def main(): """Solves the scheduling with transitions problem.""" #---------------------------------------------------------------------------- - jobs = [[[(100, 0, 'R6'), (2, 1, 'R6')]], [[(2, 0, 'R3'), (100, 1, 'R3')]], - [[(100, 0, 'R1'), (16, 1, 'R1')]], [[(1, 0, 'R1'), (38, 1, 'R1')]], - [[(14, 0, 'R1'), (10, 1, 'R1')]], [[(16, 0, 'R3'), (17, 1, 'R3')]], - [[(14, 0, 'R3'), (14, 1, 'R3')]], [[(14, 0, 'R3'), (15, 1, 'R3')]], - [[(14, 0, 'R3'), (13, 1, 'R3')]], [[(100, 0, 'R1'), (38, 1, 'R1')]]] + small_jobs = [[[(100, 0, 'R6'), (2, 1, 'R6')]], + [[(2, 0, 'R3'), (100, 1, 'R3')]], + [[(100, 0, 'R1'), (16, 1, 'R1')]], + [[(1, 0, 'R1'), (38, 1, 'R1')]], + [[(14, 0, 'R1'), (10, 1, 'R1')]], + [[(16, 0, 'R3'), (17, 1, 'R3')]], + [[(14, 0, 'R3'), (14, 1, 'R3')]], + [[(14, 0, 'R3'), (15, 1, 'R3')]], + [[(14, 0, 'R3'), (13, 1, 'R3')]], + [[(100, 0, 'R1'), (38, 1, 'R1')]]] + + large_jobs = [ + [[(-1, 0, 'R1'), (10, 1, 'R1')]], [[(9, 0, 'R3'), (22, 1, 'R3')]], + [[(-1, 0, 'R3'), (13, 1, 'R3')]], [[(-1, 0, 'R3'), (38, 1, 'R3')]], + [[(-1, 0, 'R3'), (38, 1, 'R3')]], [[(-1, 0, 'R3'), (16, 1, 'R3')]], + [[(-1, 0, 'R3'), (11, 1, 'R3')]], [[(-1, 0, 'R3'), (13, 1, 'R3')]], + [[(13, 0, 'R3'), (-1, 1, 'R3')]], [[(13, 0, 'R3'), (-1, 1, 'R3')]], + [[(-1, 0, 'R3'), (15, 1, 'R3')]], [[(12, 0, 'R1'), (-1, 1, 'R1')]], + [[(14, 0, 'R1'), (-1, 1, 'R1')]], [[(13, 0, 'R3'), (-1, 1, 'R3')]], + [[(-1, 0, 'R3'), (15, 1, 'R3')]], [[(14, 0, 'R1'), (-1, 1, 'R1')]], + [[(13, 0, 'R3'), (-1, 1, 'R3')]], [[(14, 0, 'R3'), (-1, 1, 'R3')]], + [[(13, 0, 'R1'), (-1, 1, 'R1')]], [[(15, 0, 'R1'), (-1, 1, 'R1')]], + [[(-1, 0, 'R2'), (16, 1, 'R2')]], [[(-1, 0, 'R2'), (16, 1, 'R2')]], + [[(-1, 0, 'R5'), (27, 1, 'R5')]], [[(-1, 0, 'R5'), (13, 1, 'R5')]], + [[(-1, 0, 'R5'), (13, 1, 'R5')]], [[(-1, 0, 'R5'), (13, 1, 'R5')]], + [[(13, 0, 'R1'), (-1, 1, 'R1')]], [[(-1, 0, 'R1'), (17, 1, 'R1')]], + [[(14, 0, 'R4'), (-1, 1, 'R4')]], [[(13, 0, 'R1'), (-1, 1, 'R1')]], + [[(16, 0, 'R4'), (-1, 1, 'R4')]], [[(16, 0, 'R4'), (-1, 1, 'R4')]], + [[(16, 0, 'R4'), (-1, 1, 'R4')]], [[(16, 0, 'R4'), (-1, 1, 'R4')]], + [[(13, 0, 'R1'), (-1, 1, 'R1')]], [[(13, 0, 'R1'), (-1, 1, 'R1')]], + [[(14, 0, 'R4'), (-1, 1, 'R4')]], [[(13, 0, 'R1'), (-1, 1, 'R1')]], + [[(12, 0, 'R1'), (-1, 1, 'R1')]], [[(14, 0, 'R4'), (-1, 1, 'R4')]], + [[(-1, 0, 'R5'), (14, 1, 'R5')]], [[(14, 0, 'R4'), (-1, 1, 'R4')]], + [[(14, 0, 'R4'), (-1, 1, 'R4')]], [[(14, 0, 'R4'), (-1, 1, 'R4')]], + [[(14, 0, 'R4'), (-1, 1, 'R4')]], [[(-1, 0, 'R1'), (21, 1, 'R1')]], + [[(-1, 0, 'R1'), (21, 1, 'R1')]], [[(-1, 0, 'R1'), (21, 1, 'R1')]], + [[(13, 0, 'R6'), (-1, 1, 'R6')]], [[(13, 0, 'R2'), (-1, 1, 'R2')]], + [[(-1, 0, 'R6'), (12, 1, 'R6')]], [[(13, 0, 'R1'), (-1, 1, 'R1')]], + [[(13, 0, 'R1'), (-1, 1, 'R1')]], [[(-1, 0, 'R6'), (14, 1, 'R6')]], + [[(-1, 0, 'R5'), (5, 1, 'R5')]], [[(3, 0, 'R2'), (-1, 1, 'R2')]], + [[(-1, 0, 'R1'), (21, 1, 'R1')]], [[(-1, 0, 'R1'), (21, 1, 'R1')]], + [[(-1, 0, 'R1'), (21, 1, 'R1')]], [[(-1, 0, 'R5'), (1, 1, 'R5')]], + [[(1, 0, 'R2'), (-1, 1, 'R2')]], [[(-1, 0, 'R2'), (19, 1, 'R2')]], + [[(13, 0, 'R4'), (-1, 1, 'R4')]], [[(12, 0, 'R4'), (-1, 1, 'R4')]], + [[(-1, 0, 'R3'), (2, 1, 'R3')]], [[(11, 0, 'R4'), (-1, 1, 'R4')]], + [[(6, 0, 'R6'), (-1, 1, 'R6')]], [[(6, 0, 'R6'), (-1, 1, 'R6')]], + [[(1, 0, 'R2'), (-1, 1, 'R2')]], [[(12, 0, 'R4'), (-1, 1, 'R4')]] + ] + + jobs = large_jobs #---------------------------------------------------------------------------- # Helper data. @@ -51,7 +96,7 @@ def main(): model = cp_model.CpModel() #---------------------------------------------------------------------------- - # Sum each lot longest process time for max makespan. + # Compute a maximum makespan greedily. horizon = 0 for job in jobs: for task in job: @@ -63,7 +108,7 @@ def main(): print('Horizon = %i' % horizon) #---------------------------------------------------------------------------- - # Scan the jobs and create the relevant variables and intervals. + # Global storage of variables. intervals_per_machines = collections.defaultdict(list) presences_per_machines = collections.defaultdict(list) starts_per_machines = collections.defaultdict(list) @@ -76,6 +121,8 @@ def main(): job_ranks = {} # indexed by (job_id, task_id, alt_id). job_ends = [] # indexed by job_id + #---------------------------------------------------------------------------- + # Scan the jobs and create the relevant variables and intervals. for job_id in all_jobs: job = jobs[job_id] num_tasks = len(job) @@ -223,6 +270,7 @@ def main(): # Solve. solver = cp_model.CpSolver() solver.parameters.max_time_in_seconds = 60 * 60 * 2 + solver.parameters.num_search_workers = 8 solution_printer = SolutionPrinter(makespan) status = solver.SolveWithSolutionCallback(model, solution_printer) @@ -238,6 +286,9 @@ def main(): rank = -1 for alt_id in range(len(jobs[job_id][task_id])): + if jobs[job_id][task_id][alt_id][0] == -1: + continue + if solver.BooleanValue(job_presences[(job_id, task_id, alt_id)]): duration = jobs[job_id][task_id][alt_id][0] machine = jobs[job_id][task_id][alt_id][1]