def solve_relaxed(self, mdl, prio_name, relaxable_groups, relax_mode, parameters=None): # --- 1 serialize job_name = normalize_basename(mdl.name, force_lowercase=True) model_data = self.serialize_model(mdl) docloud_parameters = mdl.parameters prm_data = self._serialize_parameters(docloud_parameters, write_level=1, relax_mode=relax_mode) prm_name = self._make_attachment_name(job_name, '.prm') feasopt_data = self._serialize_relaxables(relaxable_groups) # --- dump if need be if prio_name: prio_name = "_%s" % prio_name relax_basename = normalize_basename("%s_feasopt%s" % (mdl.name, prio_name)) prm_basename = normalize_basename("%s_feasopt" % mdl.name) self._dump_if_required(model_data, mdl, basename=job_name, extension=".lp", forced=True) self._dump_if_required(feasopt_data, mdl, basename=relax_basename, extension=FeasibilityPrinter.extension, forced=True) self._dump_if_required(prm_data, mdl, basename=prm_basename, extension=".prm", forced=True) # --- submit job somehow... attachments = [] model_name = normalize_basename(job_name) + self._exchange_format.extension attachments.append(self._make_attachment(model_name, model_data)) attachments.append(self._make_attachment(prm_name, prm_data)) attachments.append(self._make_attachment(normalize_basename(job_name) + FeasibilityPrinter.extension, feasopt_data)) # here we go... def notify_info(info): if "jobid" in info: mdl.fire_jobid(jobid=info["jobid"]) if "progress" in info: mdl.fire_progress(progress_data=info["progress"]) connector = self._connector mdl.notify_start_solve() connector.submit_model_data(attachments, gzip=not self._exchange_format.is_binary, info_callback=notify_info, info_to_monitor={'jobid', 'progress'}) # --- cplex solve details json_details = connector.get_cplex_details() self._solve_details = SolveDetails.from_json(json_details) # --- # --- build a solution object, or None solution_handler = JSONSolutionHandler(connector.results.get('solution.json')) if not solution_handler.has_solution: mdl.notify_solve_failed() return None else: infeas_json = connector.results.get('infeasibilities.json') infeas_handler = JSONInfeasibilityHandler(infeas_json) if infeas_json else None sol = self._make_relaxed_solution(mdl, solution_handler, infeas_handler) return sol
def solve(self, mdl, parameters=None, **kwargs): # Before submitting the job, we will build the list of attachments # parameters are CPLEX parameters lex_mipstart = kwargs.pop('_lex_mipstart', None) attachments = [] # make sure model is the first attachment: that will be the name of the job on the console job_name = normalize_basename("python_%s" % mdl.name) model_file = self.serialize_model_as_file(mdl) try: model_data_name = self._make_attachment_name( job_name, self._exchange_format.extension) attachments.append({ 'name': model_data_name, 'filename': model_file }) # prm docloud_parameters = parameters if parameters is not None else mdl.parameters prm_data = self._serialize_parameters(docloud_parameters) prm_name = self._make_attachment_name(job_name, '.prm') attachments.append({'name': prm_name, 'data': prm_data}) # warmstart_data # export mipstart solution in CPLEX mst format, if any, else None # if within a lexicographic solve, th elex_mipstart supersedes allother mipstarts if lex_mipstart: mipstart_name = lex_mipstart.name.lower( ) if lex_mipstart.name else job_name warmstart_data = SolutionMSTPrinter.print_to_string( lex_mipstart).encode('utf-8') warmstart_name = self._make_attachment_name( mipstart_name, ".mst") attachments.append({ 'name': warmstart_name, 'data': warmstart_data }) elif mdl.number_of_mip_starts: mipstart_name = job_name warmstart_name = self._make_attachment_name( mipstart_name, ".mst") mdl_mipstarts = [s for s, _ in mdl.iter_mip_starts()] mdl_efforts = [eff for (_, eff) in mdl.iter_mip_starts()] warmstart_data = SolutionMSTPrinter.print_to_string( mdl_mipstarts, effort_level=mdl_efforts, use_lp_names=True).encode('utf-8') attachments.append({ 'name': warmstart_name, 'data': warmstart_data }) # benders annotation if mdl.has_benders_annotations(): anno_data = ModelAnnotationPrinter.print_to_string(mdl).encode( 'utf-8') anno_name = self._make_attachment_name(job_name, '.ann') attachments.append({'name': anno_name, 'data': anno_data}) # info_to_monitor = {'jobid'} # if mdl.progress_listeners: # info_to_monitor.add('progress') def notify_info(info): if "jobid" in info: mdl.fire_jobid(jobid=info["jobid"]) if "progress" in info: mdl.fire_progress(progress_data=info["progress"]) # This block used to be try/catched for DOcloudConnector exceptions # and DOcloudException, but then infrastructure error were not # handled properly. Now we let the exception raise. connector = self._connector mdl.notify_start_solve() connector.submit_model_data( attachments, gzip=not self._exchange_format.is_binary, info_callback=notify_info, info_to_monitor={'jobid', 'progress'}) # --- cplex solve details json_details = connector.get_cplex_details() self._solve_details = SolveDetails.from_json(json_details) self._solve_details._quality_metrics = self._compute_quality_metrics( json_details) # --- # --- build a solution object, or None solution_handler = JSONSolutionHandler( connector.results.get('solution.json')) if not solution_handler.has_solution: mdl.notify_solve_failed() solution = None else: solution = self._make_solution(mdl, solution_handler) # --- return solution finally: if os.path.isfile(model_file): os.remove(model_file)