diff --git a/examples/python/appointments.py b/examples/python/appointments.py index 9f1fc56e9f..aede63f771 100644 --- a/examples/python/appointments.py +++ b/examples/python/appointments.py @@ -38,7 +38,7 @@ class AllSolutionCollector(cp_model.CpSolverSolutionCallback): self.__variables = variables self.__collect = [] - def OnSolutionCallback(self): + def on_solution_callback(self): """Collect a new combination.""" combination = [self.Value(v) for v in self.__variables] self.__collect.append(combination) diff --git a/examples/python/balance_group_sat.py b/examples/python/balance_group_sat.py index 7ac3e5ba39..6d43d69851 100644 --- a/examples/python/balance_group_sat.py +++ b/examples/python/balance_group_sat.py @@ -37,7 +37,7 @@ class SolutionPrinter(cp_model.CpSolverSolutionCallback): self.__all_items = all_items self.__item_in_group = item_in_group - def OnSolutionCallback(self): + def on_solution_callback(self): print('Solution %i' % self.__solution_count) self.__solution_count += 1 @@ -61,9 +61,6 @@ class SolutionPrinter(cp_model.CpSolverSolutionCallback): print(' (%i, %i, %i)' % (item, value, color), end='') print(']') - def SolutionCount(self): - return self.__solution_count - def main(): # Data. diff --git a/examples/python/flexible_job_shop_sat.py b/examples/python/flexible_job_shop_sat.py index ae3ab4becb..87aa7319a7 100644 --- a/examples/python/flexible_job_shop_sat.py +++ b/examples/python/flexible_job_shop_sat.py @@ -10,6 +10,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +"""Solves a flexible jobshop problems with the CP-SAT solver.""" from __future__ import print_function @@ -24,149 +25,156 @@ class SolutionPrinter(cp_model.CpSolverSolutionCallback): cp_model.CpSolverSolutionCallback.__init__(self) self.__solution_count = 0 - def OnSolutionCallback(self): + def on_solution_callback(self): + """Called at each new solution.""" print('Solution %i, time = %f s, objective = %i' % (self.__solution_count, self.WallTime(), self.ObjectiveValue())) self.__solution_count += 1 -# Data part. -jobs = [[[(3, 0), (1, 1), (5, 2)], [(2, 0), (4, 1), (6, 2)], - [(2, 0), (3, 1), (1, 2)]], - [[(2, 0), (3, 1), (4, 2)], [(1, 0), (5, 1), (4, 2)], - [(2, 0), (1, 1), (4, 2)]], - [[(2, 0), (1, 1), (4, 2)], [(2, 0), (3, 1), (4, 2)], - [(3, 0), (1, 1), (5, 2)]]] +def flexible_jobshop(): + """Solve a small flexible jobshop problem.""" + # Data part. + jobs = [[[(3, 0), (1, 1), (5, 2)], [(2, 0), (4, 1), (6, 2)], + [(2, 0), (3, 1), (1, 2)]], + [[(2, 0), (3, 1), (4, 2)], [(1, 0), (5, 1), (4, 2)], + [(2, 0), (1, 1), (4, 2)]], + [[(2, 0), (1, 1), (4, 2)], [(2, 0), (3, 1), (4, 2)], + [(3, 0), (1, 1), (5, 2)]]] -num_jobs = len(jobs) -all_jobs = range(num_jobs) + num_jobs = len(jobs) + all_jobs = range(num_jobs) -num_machines = 3 -all_machines = range(num_machines) + num_machines = 3 + all_machines = range(num_machines) -# Model the flexible jobshop problem. -model = cp_model.CpModel() + # Model the flexible jobshop problem. + model = cp_model.CpModel() -horizon = 0 -for job in jobs: - for task in job: - max_task_duration = 0 - for alternative in task: - max_task_duration = max(max_task_duration, alternative[0]) - horizon += max_task_duration + horizon = 0 + for job in jobs: + for task in job: + max_task_duration = 0 + for alternative in task: + max_task_duration = max(max_task_duration, alternative[0]) + horizon += max_task_duration -print('Horizon = %i' % horizon) + print('Horizon = %i' % horizon) -# Global storage of variables. -intervals_per_resources = defaultdict(list) -starts = {} # indexed by (job_id, task_id). -presences = {} # indexed by (job_id, task_id, alt_id). -job_ends = [] + # Global storage of variables. + intervals_per_resources = defaultdict(list) + starts = {} # indexed by (job_id, task_id). + presences = {} # indexed by (job_id, task_id, alt_id). + job_ends = [] -# Scan the jobs and create the relevant variables and intervals. -for job_id in all_jobs: - job = jobs[job_id] - num_tasks = len(job) - previous_end = None - for task_id in range(num_tasks): - task = job[task_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) + previous_end = None + for task_id in range(num_tasks): + task = job[task_id] - min_duration = task[0][0] - max_duration = task[0][0] + min_duration = task[0][0] + max_duration = task[0][0] - num_alternatives = len(task) - all_alternatives = range(num_alternatives) + num_alternatives = len(task) + all_alternatives = range(num_alternatives) - for alt_id in range(1, num_alternatives): - alt_duration = task[alt_id][0] - min_duration = min(min_duration, alt_duration) - max_duration = max(max_duration, alt_duration) + for alt_id in range(1, num_alternatives): + alt_duration = task[alt_id][0] + min_duration = min(min_duration, alt_duration) + max_duration = max(max_duration, alt_duration) - # Create main interval for the task. - suffix_name = '_j%i_t%i' % (job_id, task_id) - start = model.NewIntVar(0, horizon, 'start' + suffix_name) - duration = model.NewIntVar(min_duration, max_duration, - 'duration' + suffix_name) - end = model.NewIntVar(0, horizon, 'end' + suffix_name) - interval = model.NewIntervalVar(start, duration, end, - 'interval' + suffix_name) + # Create main interval for the task. + suffix_name = '_j%i_t%i' % (job_id, task_id) + start = model.NewIntVar(0, horizon, 'start' + suffix_name) + duration = model.NewIntVar(min_duration, max_duration, + 'duration' + suffix_name) + end = model.NewIntVar(0, horizon, 'end' + suffix_name) + interval = model.NewIntervalVar(start, duration, end, + 'interval' + suffix_name) - # Store the start for the solution. - starts[(job_id, task_id)] = start + # Store the start for the solution. + starts[(job_id, task_id)] = start - # Add precedence with previous task in the same job. - if previous_end: - model.Add(start >= previous_end) - previous_end = end + # Add precedence with previous task in the same job. + if previous_end: + model.Add(start >= previous_end) + previous_end = end - # Create alternative intervals. - if num_alternatives > 1: - l_presences = [] - for alt_id in all_alternatives: - alt_suffix = '_j%i_t%i_a%i' % (job_id, task_id, alt_id) - l_presence = model.NewBoolVar('presence' + alt_suffix) - l_start = model.NewIntVar(0, horizon, 'start' + alt_suffix) - l_duration = task[alt_id][0] - l_end = model.NewIntVar(0, horizon, 'end' + alt_suffix) - l_interval = model.NewOptionalIntervalVar( - l_start, l_duration, l_end, l_presence, - 'interval' + alt_suffix) - l_presences.append(l_presence) + # Create alternative intervals. + if num_alternatives > 1: + l_presences = [] + for alt_id in all_alternatives: + alt_suffix = '_j%i_t%i_a%i' % (job_id, task_id, alt_id) + l_presence = model.NewBoolVar('presence' + alt_suffix) + l_start = model.NewIntVar(0, horizon, 'start' + alt_suffix) + l_duration = task[alt_id][0] + l_end = model.NewIntVar(0, horizon, 'end' + alt_suffix) + l_interval = model.NewOptionalIntervalVar( + l_start, l_duration, l_end, l_presence, + 'interval' + alt_suffix) + l_presences.append(l_presence) - # Link the master variables with the local ones. - model.Add(start == l_start).OnlyEnforceIf(l_presence) - model.Add(duration == l_duration).OnlyEnforceIf(l_presence) - model.Add(end == l_end).OnlyEnforceIf(l_presence) + # Link the master variables with the local ones. + model.Add(start == l_start).OnlyEnforceIf(l_presence) + model.Add(duration == l_duration).OnlyEnforceIf(l_presence) + model.Add(end == l_end).OnlyEnforceIf(l_presence) - # Add the local interval to the right machine. - intervals_per_resources[task[alt_id][1]].append(l_interval) + # Add the local interval to the right machine. + intervals_per_resources[task[alt_id][1]].append(l_interval) - # Store the presences for the solution. - presences[(job_id, task_id, alt_id)] = l_presence + # Store the presences for the solution. + presences[(job_id, task_id, alt_id)] = l_presence - # Select exactly one presence variable. - model.Add(sum(l_presences) == 1) - else: - intervals_per_resources[task[0][1]].append(interval) - presences[(job_id, task_id, 0)] = model.NewConstant(1) + # Select exactly one presence variable. + model.Add(sum(l_presences) == 1) + else: + intervals_per_resources[task[0][1]].append(interval) + presences[(job_id, task_id, 0)] = model.NewConstant(1) - job_ends.append(previous_end) + job_ends.append(previous_end) -# Create machines constraints. -for machine_id in all_machines: - intervals = intervals_per_resources[machine_id] - if len(intervals) > 1: - model.AddNoOverlap(intervals) + # Create machines constraints. + for machine_id in all_machines: + intervals = intervals_per_resources[machine_id] + if len(intervals) > 1: + model.AddNoOverlap(intervals) -# Makespan objective -makespan = model.NewIntVar(0, horizon, 'makespan') -model.AddMaxEquality(makespan, job_ends) -model.Minimize(makespan) + # Makespan objective + makespan = model.NewIntVar(0, horizon, 'makespan') + model.AddMaxEquality(makespan, job_ends) + model.Minimize(makespan) -# Solve model. -solver = cp_model.CpSolver() -solution_printer = SolutionPrinter() -status = solver.SolveWithSolutionCallback(model, solution_printer) + # Solve model. + solver = cp_model.CpSolver() + solution_printer = SolutionPrinter() + status = solver.SolveWithSolutionCallback(model, solution_printer) -# Print final solution. -for job_id in all_jobs: - print('Job %i:' % job_id) - for task_id in range(len(jobs[job_id])): - start_value = solver.Value(starts[(job_id, task_id)]) - machine = -1 - duration = -1 - selected = -1 - for alt_id in range(len(jobs[job_id][task_id])): - if solver.Value(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] - selected = alt_id - print(' task_%i_%i starts at %i (alt %i, machine %i, duration %i)' % - (job_id, task_id, start_value, selected, machine, duration)) + # Print final solution. + for job_id in all_jobs: + print('Job %i:' % job_id) + for task_id in range(len(jobs[job_id])): + start_value = solver.Value(starts[(job_id, task_id)]) + machine = -1 + duration = -1 + selected = -1 + for alt_id in range(len(jobs[job_id][task_id])): + if solver.Value(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] + selected = alt_id + print( + ' task_%i_%i starts at %i (alt %i, machine %i, duration %i)' % + (job_id, task_id, start_value, selected, machine, duration)) -print('Solve status: %s' % solver.StatusName(status)) -print('Optimal objective value: %i' % solver.ObjectiveValue()) -print('Statistics') -print(' - conflicts : %i' % solver.NumConflicts()) -print(' - branches : %i' % solver.NumBranches()) -print(' - wall time : %f s' % solver.WallTime()) + print('Solve status: %s' % solver.StatusName(status)) + print('Optimal objective value: %i' % solver.ObjectiveValue()) + print('Statistics') + print(' - conflicts : %i' % solver.NumConflicts()) + print(' - branches : %i' % solver.NumBranches()) + print(' - wall time : %f s' % solver.WallTime()) + + +flexible_jobshop() diff --git a/examples/python/nqueens_sat.py b/examples/python/nqueens_sat.py index 6e30efefe1..f459190d9d 100644 --- a/examples/python/nqueens_sat.py +++ b/examples/python/nqueens_sat.py @@ -26,10 +26,10 @@ class NQueenSolutionPrinter(cp_model.CpSolverSolutionCallback): self.__solution_count = 0 self.__start_time = time.time() - def SolutionCount(self): + def solution_count(self): return self.__solution_count - def OnSolutionCallback(self): + def on_solution_callback(self): current_time = time.time() print('Solution %i, time = %f s' % (self.__solution_count, current_time - self.__start_time)) @@ -87,7 +87,7 @@ def main(board_size): print(' - conflicts : %i' % solver.NumConflicts()) print(' - branches : %i' % solver.NumBranches()) print(' - wall time : %f ms' % solver.WallTime()) - print(' - solutions found : %i' % solution_printer.SolutionCount()) + print(' - solutions found : %i' % solution_printer.solution_count()) # By default, solve the 8x8 problem. diff --git a/examples/python/nurses_sat.py b/examples/python/nurses_sat.py index ab2e5882b9..9f7308a6c0 100644 --- a/examples/python/nurses_sat.py +++ b/examples/python/nurses_sat.py @@ -28,7 +28,7 @@ class NursesPartialSolutionPrinter(cp_model.CpSolverSolutionCallback): self.__solutions = set(sols) self.__solution_count = 0 - def OnSolutionCallback(self): + def on_solution_callback(self): self.__solution_count += 1 if self.__solution_count in self.__solutions: print('Solution #%i' % self.__solution_count) @@ -40,7 +40,7 @@ class NursesPartialSolutionPrinter(cp_model.CpSolverSolutionCallback): print(' Nurse #%i is working shift #%i' % (n, s)) print() - def SolutionCount(self): + def solution_count(self): return self.__solution_count @@ -126,7 +126,7 @@ def main(): print(' - conflicts : %i' % solver.NumConflicts()) print(' - branches : %i' % solver.NumBranches()) print(' - wall time : %f ms' % solver.WallTime()) - print(' - solutions found : %i' % solution_printer.SolutionCount()) + print(' - solutions found : %i' % solution_printer.solution_count()) if __name__ == '__main__': diff --git a/examples/python/qubo_sat.py b/examples/python/qubo_sat.py index f1070ad27b..11d3b1d475 100644 --- a/examples/python/qubo_sat.py +++ b/examples/python/qubo_sat.py @@ -650,7 +650,7 @@ class ObjectiveSolutionPrinter(cp_model.CpSolverSolutionCallback): self.__solution_count = 0 self.__start_time = time.time() - def OnSolutionCallback(self): + def on_solution_callback(self): """Called at each new solution.""" current_time = time.time() objective = self.ObjectiveValue() @@ -659,7 +659,7 @@ class ObjectiveSolutionPrinter(cp_model.CpSolverSolutionCallback): objective, self.BestObjectiveBound())) self.__solution_count += 1 - def SolutionCount(self): + def solution_count(self): return self.__solution_count def solve_qubo(): @@ -706,7 +706,7 @@ def solve_qubo(): print(' - conflicts : %i' % solver.NumConflicts()) print(' - branches : %i' % solver.NumBranches()) print(' - wall time : %f ms' % solver.WallTime()) - print(' - solutions found : %i' % solution_printer.SolutionCount()) + print(' - solutions found : %i' % solution_printer.solution_count()) if __name__ == '__main__': diff --git a/examples/python/rcpsp_sat.py b/examples/python/rcpsp_sat.py index 15debd0c71..cc618b99c6 100644 --- a/examples/python/rcpsp_sat.py +++ b/examples/python/rcpsp_sat.py @@ -24,15 +24,15 @@ from google.protobuf import text_format from ortools.data import pywraprcpsp from ortools.sat.python import cp_model -Parser = argparse.ArgumentParser() -Parser.add_argument( +PARSER = argparse.ArgumentParser() +PARSER.add_argument( '--input', default="", help='Input file to parse and solve.') -Parser.add_argument( +PARSER.add_argument( '--output_proto', default="", help='Output file to write the cp_model' 'proto to.') -Parser.add_argument('--params', default="", help='Sat solver parameters.') +PARSER.add_argument('--params', default="", help='Sat solver parameters.') class SolutionPrinter(cp_model.CpSolverSolutionCallback): @@ -43,7 +43,7 @@ class SolutionPrinter(cp_model.CpSolverSolutionCallback): self.__solution_count = 0 self.__start_time = time.time() - def OnSolutionCallback(self): + def on_solution_callback(self): current_time = time.time() objective = self.ObjectiveValue() print('Solution %i, time = %f s, objective = %i' % @@ -52,7 +52,7 @@ class SolutionPrinter(cp_model.CpSolverSolutionCallback): self.__solution_count += 1 -def SolveRcpsp(problem, proto_file, params): +def solve_rcpsp(problem, proto_file, params): """Parse and solve a given RCPSP problem in proto format.""" # Determine problem type. @@ -286,8 +286,8 @@ def SolveRcpsp(problem, proto_file, params): def main(args): rcpsp_parser = pywraprcpsp.RcpspParser() rcpsp_parser.ParseFile(args.input) - SolveRcpsp(rcpsp_parser.Problem(), args.output_proto, args.params) + solve_rcpsp(rcpsp_parser.Problem(), args.output_proto, args.params) if __name__ == '__main__': - main(Parser.parse_args()) + main(PARSER.parse_args()) diff --git a/examples/python/shift_scheduling_sat.py b/examples/python/shift_scheduling_sat.py index 64bd4d329a..0de1ada719 100644 --- a/examples/python/shift_scheduling_sat.py +++ b/examples/python/shift_scheduling_sat.py @@ -21,13 +21,13 @@ from google.protobuf import text_format from ortools.sat.python import cp_model -Parser = argparse.ArgumentParser() -Parser.add_argument( +PARSER = argparse.ArgumentParser() +PARSER.add_argument( '--output_proto', default="", help='Output file to write the cp_model' 'proto to.') -Parser.add_argument('--params', default="", help='Sat solver parameters.') +PARSER.add_argument('--params', default="", help='Sat solver parameters.') class ObjectiveSolutionPrinter(cp_model.CpSolverSolutionCallback): @@ -38,7 +38,7 @@ class ObjectiveSolutionPrinter(cp_model.CpSolverSolutionCallback): self.__solution_count = 0 self.__start_time = time.time() - def OnSolutionCallback(self): + def on_solution_callback(self): """Called on each new solution.""" current_time = time.time() objective = self.ObjectiveValue() @@ -47,7 +47,7 @@ class ObjectiveSolutionPrinter(cp_model.CpSolverSolutionCallback): objective, self.BestObjectiveBound())) self.__solution_count += 1 - def SolutionCount(self): + def solution_count(self): """Returns the number of solutions found.""" return self.__solution_count @@ -453,7 +453,7 @@ def solve_shift_scheduling(params, output_proto): print(' - conflicts : %i' % solver.NumConflicts()) print(' - branches : %i' % solver.NumBranches()) print(' - wall time : %f ms' % solver.WallTime()) - print(' - solutions found : %i' % solution_printer.SolutionCount()) + print(' - solutions found : %i' % solution_printer.solution_count()) def main(args): @@ -462,4 +462,4 @@ def main(args): if __name__ == '__main__': - main(Parser.parse_args()) + main(PARSER.parse_args()) diff --git a/examples/python/single_machine_scheduling_with_setup_release_due_dates_sat.py b/examples/python/single_machine_scheduling_with_setup_release_due_dates_sat.py index 082f4ff344..dba2d55ebc 100644 --- a/examples/python/single_machine_scheduling_with_setup_release_due_dates_sat.py +++ b/examples/python/single_machine_scheduling_with_setup_release_due_dates_sat.py @@ -45,7 +45,7 @@ class SolutionPrinter(cp_model.CpSolverSolutionCallback): cp_model.CpSolverSolutionCallback.__init__(self) self.__solution_count = 0 - def OnSolutionCallback(self): + def on_solution_callback(self): print('Solution %i, time = %f s, objective = %i' % (self.__solution_count, self.WallTime(), self.ObjectiveValue())) self.__solution_count += 1 diff --git a/examples/python/steel_mill_slab_sat.py b/examples/python/steel_mill_slab_sat.py index 13c9dbd545..3d36cc1b17 100644 --- a/examples/python/steel_mill_slab_sat.py +++ b/examples/python/steel_mill_slab_sat.py @@ -36,7 +36,7 @@ PARSER.add_argument( help='Output file to write the cp_model proto to.') -def BuildProblem(problem_id): +def build_problem(problem_id): """Build problem data.""" if problem_id == 0: capacities = [ @@ -270,7 +270,7 @@ class SteelMillSlabSolutionPrinter(cp_model.CpSolverSolutionCallback): self.__all_slabs = range(len(assign[0])) self.__start_time = time.time() - def OnSolutionCallback(self): + def on_solution_callback(self): current_time = time.time() objective = sum(self.Value(l) for l in self.__loss) print('Solution %i, time = %f s, objective = %i' % @@ -299,7 +299,7 @@ class SolutionPrinterWithObjective(cp_model.CpSolverSolutionCallback): self.__solution_count = 0 self.__start_time = time.time() - def OnSolutionCallback(self): + def on_solution_callback(self): current_time = time.time() print('Solution %i, time = %f s, objective = %i' % (self.__solution_count, current_time - self.__start_time, @@ -307,10 +307,10 @@ class SolutionPrinterWithObjective(cp_model.CpSolverSolutionCallback): self.__solution_count += 1 -def SteelMillSlab(problem, break_symmetries, output_proto): +def steel_mill_slab(problem, break_symmetries, output_proto): """Solves the Steel Mill Slab Problem.""" ### Load problem. - (num_slabs, capacities, num_colors, orders) = BuildProblem(problem) + (num_slabs, capacities, num_colors, orders) = build_problem(problem) num_orders = len(orders) num_capacities = len(capacities) @@ -458,15 +458,15 @@ class AllSolutionsCollector(cp_model.CpSolverSolutionCallback): self.__solutions = [] self.__variables = variables - def OnSolutionCallback(self): + def on_solution_callback(self): solution = [self.Value(v) for v in self.__variables] self.__solutions.append(tuple(solution)) - def AllSolutions(self): + def all_solutions(self): return self.__solutions -def CollectValidSlabs(capacities, colors, widths, loss_array, all_colors): +def collect_valid_slabs(capacities, colors, widths, loss_array, all_colors): """Collect valid columns (assign, loss) for one slab.""" max_capacity = max(capacities) all_orders = range(len(colors)) @@ -505,13 +505,13 @@ def CollectValidSlabs(capacities, colors, widths, loss_array, all_colors): collector = AllSolutionsCollector(assign + [loss, load]) solver.SearchForAllSolutions(model, collector) print('Collect Valid Slabs...DONE') - return collector.AllSolutions() + return collector.all_solutions() -def SteelMillSlabWithValidSlabs(problem, break_symmetries, output_proto): +def steel_mill_slab_with_valid_slabs(problem, break_symmetries, output_proto): """Solves the Steel Mill Slab Problem.""" ### Load problem. - (num_slabs, capacities, num_colors, orders) = BuildProblem(problem) + (num_slabs, capacities, num_colors, orders) = build_problem(problem) num_orders = len(orders) num_capacities = len(capacities) @@ -543,8 +543,8 @@ def SteelMillSlabWithValidSlabs(problem, break_symmetries, output_proto): ] losses = [model.NewIntVar(0, max_loss, 'loss_%i' % s) for s in all_slabs] - unsorted_valid_slabs = CollectValidSlabs(capacities, colors, widths, - loss_array, all_colors) + unsorted_valid_slabs = collect_valid_slabs(capacities, colors, widths, + loss_array, all_colors) # Sort slab by descending load/loss. Remove duplicates. valid_slabs = sorted( unsorted_valid_slabs, key=lambda c: 1000 * c[-1] + c[-2]) @@ -646,14 +646,13 @@ def SteelMillSlabWithValidSlabs(problem, break_symmetries, output_proto): print('No solution') -def SteelMillSlabWithColumnGeneration(problem, output_proto): +def steel_mill_slab_with_column_generation(problem, output_proto): """Solves the Steel Mill Slab Problem.""" ### Load problem. - (num_slabs, capacities, num_colors, orders) = BuildProblem(problem) + (num_slabs, capacities, num_colors, orders) = build_problem(problem) num_orders = len(orders) num_capacities = len(capacities) - all_slabs = range(num_slabs) all_colors = range(num_colors) all_orders = range(len(orders)) print('Solving steel mill with %i orders, %i slabs, and %i capacities' % @@ -671,8 +670,8 @@ def SteelMillSlabWithColumnGeneration(problem, output_proto): ### Model problem. # Generate all valid slabs (columns) - unsorted_valid_slabs = CollectValidSlabs(capacities, colors, widths, - loss_array, all_colors) + unsorted_valid_slabs = collect_valid_slabs(capacities, colors, widths, + loss_array, all_colors) # Sort slab by descending load/loss. Remove duplicates. valid_slabs = sorted( unsorted_valid_slabs, key=lambda c: 1000 * c[-1] + c[-2]) @@ -722,14 +721,13 @@ def SteelMillSlabWithColumnGeneration(problem, output_proto): print('No solution') -def SteelMillSlabWithMipColumnGeneration(problem): +def steel_mill_slab_with_mip_column_generation(problem): """Solves the Steel Mill Slab Problem.""" ### Load problem. - (num_slabs, capacities, num_colors, orders) = BuildProblem(problem) + (num_slabs, capacities, num_colors, orders) = build_problem(problem) num_orders = len(orders) num_capacities = len(capacities) - all_slabs = range(num_slabs) all_colors = range(num_colors) all_orders = range(len(orders)) print('Solving steel mill with %i orders, %i slabs, and %i capacities' % @@ -748,8 +746,8 @@ def SteelMillSlabWithMipColumnGeneration(problem): # Generate all valid slabs (columns) start = time.time() - unsorted_valid_slabs = CollectValidSlabs(capacities, colors, widths, - loss_array, all_colors) + unsorted_valid_slabs = collect_valid_slabs(capacities, colors, widths, + loss_array, all_colors) # Sort slab by descending load/loss. Remove duplicates. valid_slabs = sorted( unsorted_valid_slabs, key=lambda c: 1000 * c[-1] + c[-2]) @@ -792,14 +790,14 @@ def SteelMillSlabWithMipColumnGeneration(problem): def main(args): '''Main function''' if args.solver == 'sat': - SteelMillSlab(args.problem, args.break_symmetries, args.output_proto) + steel_mill_slab(args.problem, args.break_symmetries, args.output_proto) elif args.solver == 'sat_table': - SteelMillSlabWithValidSlabs(args.problem, args.break_symmetries, - args.output_proto) + steel_mill_slab_with_valid_slabs(args.problem, args.break_symmetries, + args.output_proto) elif args.solver == 'sat_column': - SteelMillSlabWithColumnGeneration(args.problem, args.output_proto) + steel_mill_slab_with_column_generation(args.problem, args.output_proto) else: # 'mip_column' - SteelMillSlabWithMipColumnGeneration(args.problem) + steel_mill_slab_with_mip_column_generation(args.problem) if __name__ == '__main__': diff --git a/examples/python/tasks_and_workers_assignment_sat.py b/examples/python/tasks_and_workers_assignment_sat.py index e1d1d4f45f..74b985054e 100644 --- a/examples/python/tasks_and_workers_assignment_sat.py +++ b/examples/python/tasks_and_workers_assignment_sat.py @@ -24,7 +24,7 @@ class ObjectivePrinter(cp_model.CpSolverSolutionCallback): cp_model.CpSolverSolutionCallback.__init__(self) self.__solution_count = 0 - def OnSolutionCallback(self): + def on_solution_callback(self): print('Solution %i, time = %f s, objective = %i' % (self.__solution_count, self.WallTime(), self.ObjectiveValue())) self.__solution_count += 1 diff --git a/examples/python/vendor_scheduling_sat.py b/examples/python/vendor_scheduling_sat.py index fecf35dc59..166e61e4c7 100644 --- a/examples/python/vendor_scheduling_sat.py +++ b/examples/python/vendor_scheduling_sat.py @@ -33,7 +33,7 @@ class SolutionPrinter(cp_model.CpSolverSolutionCallback): self.__hours_stat = hours_stat self.__min_vendors = min_vendors - def OnSolutionCallback(self): + def on_solution_callback(self): """Called at each new solution.""" self.__solution_count += 1 print('Solution %i: ', self.__solution_count) @@ -50,7 +50,7 @@ class SolutionPrinter(cp_model.CpSolverSolutionCallback): print() print() - def SolutionCount(self): + def solution_count(self): """Returns the number of solution found.""" return self.__solution_count @@ -137,8 +137,8 @@ def main(): print(' - conflicts : %i' % solver.NumConflicts()) print(' - branches : %i' % solver.NumBranches()) print(' - wall time : %f s' % solver.WallTime()) - print( - ' - number of solutions found: %i' % solution_printer.SolutionCount()) + print(' - number of solutions found: %i' % + solution_printer.solution_count()) if __name__ == '__main__': diff --git a/examples/python/wedding_optimal_chart_sat.py b/examples/python/wedding_optimal_chart_sat.py index 45f1704e18..1f2d4c2c2b 100644 --- a/examples/python/wedding_optimal_chart_sat.py +++ b/examples/python/wedding_optimal_chart_sat.py @@ -53,7 +53,7 @@ class WeddingChartPrinter(cp_model.CpSolverSolutionCallback): self.__num_tables = num_tables self.__num_guests = num_guests - def OnSolutionCallback(self): + def on_solution_callback(self): current_time = time.time() objective = self.ObjectiveValue() print("Solution %i, time = %f s, objective = %i" % @@ -67,7 +67,7 @@ class WeddingChartPrinter(cp_model.CpSolverSolutionCallback): if self.Value(self.__seats[(t, g)]): print(" " + self.__names[g]) - def NumSolutions(self): + def num_solutions(self): return self.__solution_count @@ -116,7 +116,7 @@ def BuildData(): return num_tables, table_capacity, min_known_neighbors, C, names -def SolveWithDiscreteModel(): +def solve_with_discrete_model(): num_tables, table_capacity, min_known_neighbors, C, names = BuildData() num_guests = len(C) @@ -203,12 +203,7 @@ def SolveWithDiscreteModel(): print(" - conflicts : %i" % solver.NumConflicts()) print(" - branches : %i" % solver.NumBranches()) print(" - wall time : %f ms" % solver.WallTime()) - print(" - num solutions: %i" % solution_printer.NumSolutions()) + print(" - num solutions: %i" % solution_printer.num_solutions()) -def main(): - SolveWithDiscreteModel() - - -if __name__ == "__main__": - main() +solve_with_discrete_model() diff --git a/ortools/sat/python/cp_model.py b/ortools/sat/python/cp_model.py index 46e5590c38..1bdbf797d3 100644 --- a/ortools/sat/python/cp_model.py +++ b/ortools/sat/python/cp_model.py @@ -1374,6 +1374,11 @@ class CpSolverSolutionCallback(pywrapsat.SolutionCallback): and Value() methods. """ + def OnSolutionCallback(self): + """Proxy to the same method with different naming convention.""" + self.on_solution_callback() + + def BooleanValue(self, lit): """Returns the boolean value of a boolean literal. diff --git a/ortools/sat/samples/channeling_sample_sat.py b/ortools/sat/samples/channeling_sample_sat.py index fa73f2aa7a..25a37fff52 100644 --- a/ortools/sat/samples/channeling_sample_sat.py +++ b/ortools/sat/samples/channeling_sample_sat.py @@ -27,13 +27,13 @@ class VarArraySolutionPrinter(cp_model.CpSolverSolutionCallback): self.__variables = variables self.__solution_count = 0 - def OnSolutionCallback(self): + def on_solution_callback(self): self.__solution_count += 1 for v in self.__variables: print('%s=%i' % (v, self.Value(v)), end=' ') print() - def SolutionCount(self): + def solution_count(self): return self.__solution_count diff --git a/ortools/sat/samples/cp_is_fun_sat.py b/ortools/sat/samples/cp_is_fun_sat.py index 9d12d9c111..10837e57c7 100644 --- a/ortools/sat/samples/cp_is_fun_sat.py +++ b/ortools/sat/samples/cp_is_fun_sat.py @@ -34,13 +34,13 @@ class VarArraySolutionPrinter(cp_model.CpSolverSolutionCallback): self.__variables = variables self.__solution_count = 0 - def OnSolutionCallback(self): + def on_solution_callback(self): self.__solution_count += 1 for v in self.__variables: print('%s=%i' % (v, self.Value(v)), end=' ') print() - def SolutionCount(self): + def solution_count(self): return self.__solution_count # [END solution_printing] @@ -93,7 +93,7 @@ def CPIsFunSat(): print(' - conflicts : %i' % solver.NumConflicts()) print(' - branches : %i' % solver.NumBranches()) print(' - wall time : %f ms' % solver.WallTime()) - print(' - solutions found : %i' % solution_printer.SolutionCount()) + print(' - solutions found : %i' % solution_printer.solution_count()) if __name__ == '__main__': diff --git a/ortools/sat/samples/search_for_all_solutions_sample_sat.py b/ortools/sat/samples/search_for_all_solutions_sample_sat.py index ef1eebf8b7..29be9f3092 100644 --- a/ortools/sat/samples/search_for_all_solutions_sample_sat.py +++ b/ortools/sat/samples/search_for_all_solutions_sample_sat.py @@ -29,13 +29,13 @@ class VarArraySolutionPrinter(cp_model.CpSolverSolutionCallback): self.__variables = variables self.__solution_count = 0 - def OnSolutionCallback(self): + def on_solution_callback(self): self.__solution_count += 1 for v in self.__variables: print('%s=%i' % (v, self.Value(v)), end=' ') print() - def SolutionCount(self): + def solution_count(self): return self.__solution_count # [END print_solution] @@ -68,7 +68,7 @@ def SearchForAllSolutionsSampleSat(): # [END solve] print('Status = %s' % solver.StatusName(status)) - print('Number of solutions found: %i' % solution_printer.SolutionCount()) + print('Number of solutions found: %i' % solution_printer.solution_count()) SearchForAllSolutionsSampleSat() diff --git a/ortools/sat/samples/solve_and_print_intermediate_solutions_sample_sat.py b/ortools/sat/samples/solve_and_print_intermediate_solutions_sample_sat.py index 2b133bd5c5..28f9b03555 100644 --- a/ortools/sat/samples/solve_and_print_intermediate_solutions_sample_sat.py +++ b/ortools/sat/samples/solve_and_print_intermediate_solutions_sample_sat.py @@ -30,7 +30,7 @@ class VarArrayAndObjectiveSolutionPrinter(cp_model.CpSolverSolutionCallback): self.__variables = variables self.__solution_count = 0 - def OnSolutionCallback(self): + def on_solution_callback(self): print('Solution %i' % self.__solution_count) print(' objective value = %i' % self.ObjectiveValue()) for v in self.__variables: @@ -38,7 +38,7 @@ class VarArrayAndObjectiveSolutionPrinter(cp_model.CpSolverSolutionCallback): print() self.__solution_count += 1 - def SolutionCount(self): + def solution_count(self): return self.__solution_count # [END print_solution] @@ -75,7 +75,7 @@ def SolveAndPrintIntermediateSolutionsSampleSat(): # [END solve] print('Status = %s' % solver.StatusName(status)) - print('Number of solutions found: %i' % solution_printer.SolutionCount()) + print('Number of solutions found: %i' % solution_printer.solution_count()) SolveAndPrintIntermediateSolutionsSampleSat() diff --git a/ortools/sat/samples/stop_after_n_solutions_sample_sat.py b/ortools/sat/samples/stop_after_n_solutions_sample_sat.py index ec12a3831c..30925c04ce 100644 --- a/ortools/sat/samples/stop_after_n_solutions_sample_sat.py +++ b/ortools/sat/samples/stop_after_n_solutions_sample_sat.py @@ -28,7 +28,7 @@ class VarArraySolutionPrinterWithLimit(cp_model.CpSolverSolutionCallback): self.__solution_count = 0 self.__solution_limit = limit - def OnSolutionCallback(self): + def on_solution_callback(self): self.__solution_count += 1 for v in self.__variables: print('%s=%i' % (v, self.Value(v)), end=' ') @@ -37,7 +37,7 @@ class VarArraySolutionPrinterWithLimit(cp_model.CpSolverSolutionCallback): print('Stop search after %i solutions' % self.__solution_limit) self.StopSearch() - def SolutionCount(self): + def solution_count(self): return self.__solution_count @@ -56,8 +56,8 @@ def StopAfterNSolutionsSampleSat(): solution_printer = VarArraySolutionPrinterWithLimit([x, y, z], 5) status = solver.SearchForAllSolutions(model, solution_printer) print('Status = %s' % solver.StatusName(status)) - print('Number of solutions found: %i' % solution_printer.SolutionCount()) - assert solution_printer.SolutionCount() == 5 + print('Number of solutions found: %i' % solution_printer.solution_count()) + assert solution_printer.solution_count() == 5 StopAfterNSolutionsSampleSat()