安裝Google ORTools ```Python #!python -m pip install --upgrade --user ortools ``` 範例程式碼 ```Python= import collections from ortools.sat.python import cp_model # sat是專門用來解條件優化的解 # Create the model. model = cp_model.CpModel() my_job_list = [ # task = (machine_id, processing_time). 0車床A 1車床B 2銑床C 3銑床D 4磨床E 5CMM [(0,1,0),(1,2,0),(4,4,0),(5,4,0)], #wo#0 [(0,1,1),(1,2,1),(4,4,1),(5,4,1)], #wo#1 [(0,1,2),(2,4,2),(4,6,2),(5,2,2)], #wo#2 [(2,1,3),(3,3,3),(5,1,3)], #wo#3 [(1,1,4),(3,7,4),(5,3,4)], #wo#4 [(1,1,5),(3,7,5),(5,3,5)] #wo#5 ] jobs_count = 6 all_jobs = [0,1,2,3,4,5] all_machines = [0,1,2,3,4,5] # Compute horizon. horizon = sum(task[1] for job in my_job_list for task in job) task_type = collections.namedtuple('task_type', 'start end interval') assigned_task_type = collections.namedtuple('assigned_task_type','start job index') #NewIntVar設至非連續整數型變數 all_tasks = {} for job in all_jobs: for task_id, task in enumerate(my_task[job]): start_var = model.NewIntVar(0, horizon,'start_%i_%i' % (job, task_id)) duration = task[1] end_var = model.NewIntVar(0, horizon, 'end_%i_%i' % (job, task_id)) interval_var = model.NewIntervalVar(start_var, duration, end_var, 'interval_%i_%i' % (job, task_id)) all_tasks[job, task_id] = task_type(start=start_var, end=end_var, interval=interval_var) # Create and add disjunctive constraints. # AddNoOverlap使參數中時間 間格無法重疊 for machine in all_machines: intervals = [] for job in all_jobs: for task_id, task in enumerate(my_job_list[job]): if task[0] == machine: intervals.append(all_tasks[job, task_id].interval) model.AddNoOverlap(intervals) # Add precedence contraints. for job in all_jobs: for task_id in range(0, len(my_job_list[job]) - 1): model.Add(all_tasks[job, task_id +1].start >= all_tasks[job, task_id].end) # Makespan objective. #AddMaxEquality Minimize做最大最小近似值 obj_var = model.NewIntVar(0, horizon, 'makespan') model.AddMaxEquality( obj_var, [all_tasks[(job, len(my_job_list[job]) - 1)].end for job in all_jobs]) model.Minimize(obj_var) # Solve model. #CpSolver 模型中的求解器 solver = cp_model.CpSolver() status = solver.Solve(model) if status == cp_model.OPTIMAL: # Print out makespan. print('Optimal Schedule Length: %i' % solver.ObjectiveValue()) print() # Create one list of assigned tasks per machine. assigned_jobs = [[] for _ in all_machines] for job in all_jobs: for task_id, task in enumerate(my_job_list[job]): machine = task[0] assigned_jobs[machine].append( assigned_task_type( start=solver.Value(all_tasks[job, task_id].start), job=job, index=task_id)) disp_col_width = 10 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) + ': ' 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)) start = assigned_task.start duration = my_job_list[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 += '\n' sol_line_tasks += '\n' print(sol_line_tasks) print('Task Time Intervals\n') print(sol_line)