def _add_callback_if_needed(self): """ Ask solver to add callback if needed. """ if not self.callback_proto and self.solver.callbacks: # Check solver version lver = self.version_info.get('LibVersion', 0) sver = self.version_info.get('SolverVersion', "1") if (compare_natural(sver, "12.10") >= 0) and (lver >= 2): # Create session # CAUTION: storing callback prototype is mandatory. Otherwise, it is garbaged and the callback fails. self.callback_proto = _CPE_CALLBACK_PROTOTYPE( self._cpo_callback) self._call_lib_function('setCpoCallback', False, self.callback_proto) self.context.log(3, "CPO callback created.") else: raise CpoLibException( "This version of the CPO solver does not support solver callbacks. Solver: {}, lib: {}" .format(sver, lver))
def __init__(self, solver, params, context): """ Create a new solver using shared library. Args: solver: Parent solver params: Solving parameters context: Solver agent context Raises: CpoLibException if library is not found """ # Call super super(CpoSolverLib, self).__init__(solver, params, context) # Initialize attributes self.first_error_line = None self.lib_handler = None # (to not block end() in case of init failure) self.last_conflict_cpo = None # Connect to library self.lib_handler = self._get_lib_handler() self.context.log(2, "Solving library: '{}'".format(self.context.lib)) # Create session # CAUTION: storing callback prototype is mandatory. Otherwise, it is garbaged and the callback fails. self.notify_event_proto = _EVENT_NOTIF_PROTOTYPE(self._notify_event) self.session = self.lib_handler.createSession(self.notify_event_proto) self.context.log(5, "Solve session: {}".format(self.session)) # Check solver version if any sver = self.version_info.get('SolverVersion') mver = solver.get_model_format_version() if sver and mver and compare_natural(mver, sver) > 0: raise CpoLibException( "Solver version {} is lower than model format version {}.". format(sver, mver)) # Send CPO model to solver cpostr = self._get_cpo_model_string() self._set_cpo_model(cpostr) self.context.log(3, "Model set into solver.") # Initialize CPO callback setting self.callback_proto = None
#----------------------------------------------------------------------------- # Solve the model, tracking objective with a callback #----------------------------------------------------------------------------- class MyCallback(CpoCallback): def invoke(self, solver, event, jsol): # Get important elements obj_val = jsol.get_objective_values() obj_bnds = jsol.get_objective_bounds() obj_gaps = jsol.get_objective_gaps() solvests = jsol.get_solve_status() srchsts = jsol.get_search_status() #allvars = jsol.get_solution().get_all_var_solutions() if jsol.is_solution() else None solve_time = jsol.get_info('SolveTime') memory = jsol.get_info('MemoryUsage') print( "CALLBACK: {}: {}, {}, objective: {} bounds: {}, gaps: {}, time: {}, memory: {}" .format(event, solvests, srchsts, obj_val, obj_bnds, obj_gaps, solve_time, memory)) if compare_natural(solver.get_solver_version(), '12.10') >= 0: mdl.add_solver_callback(MyCallback()) # Solve the model print("Solve the model") msol = mdl.solve(TimeLimit=10) msol.write()
# Associate plant openness to its load for p in range(nbLocation): mdl.add(open[p] == (load[p] > 0)) # Add constraints mdl.add(mdl.pack(load, cust, demand)) # Add objective obj = mdl.scal_prod(fixedCost, open) for c in range(nbCustomer): obj += mdl.element(cust[c], cost[c]) mdl.add(mdl.minimize(obj)) # Add KPIs if compare_natural(context.model.version, '12.9') >= 0: mdl.add_kpi(mdl.sum(demand) / mdl.scal_prod(open, capacity), "Average Occupancy") mdl.add_kpi(mdl.min([load[l] / capacity[l] + (1 - open[l]) for l in range(nbLocation)]), "Min occupancy") #----------------------------------------------------------------------------- # Solve the model and display the result #----------------------------------------------------------------------------- if context.visu_enabled: mdl.add_solver_listener(SolverProgressPanelListener(parse_log=True)) # Solve the model print("Solve the model") msol = mdl.solve(TimeLimit=20, LogPeriod=1000) msol.write()