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)
def export_one_mip_start(self, mipstart, job_name, attachments): warmstart_data = SolutionMSTPrinter.print_to_string(mipstart).encode( 'utf-8') mipstart_name = mipstart.name.lower() if mipstart.name else job_name warmstart_name = self._make_attachment_name(mipstart_name, ".mst") attachments.append({'name': warmstart_name, 'data': warmstart_data})