def solve(self, options): # takes into account successors jobs = copy.deepcopy(self.instance.data["jobs"]) all_jobs = set(jobs.keys()) solution = pt.SuperDict() succ = jobs.get_property("successors") durations = self.instance.data["durations"] # algorithm period = 0 job = 1 succ.pop(job) mode = 1 # we always chose the first mode solution[job] = dict(period=period, mode=mode) period = period + durations[job][mode] while len(succ): reverse = succ.list_reverse() possible = all_jobs - reverse.keys() - solution.keys() for job in possible: succ.pop(job) solution[job] = dict(period=period, mode=mode) period = period + durations[job][mode] self.solution = Solution(solution) return 2
def solve(self, options=None, print_file=False): """ Solve the problem. """ log.debug(options) model = get_model() data = self.get_input_data() if options is None: options = {} if "timeLimit" in options: if "SOLVER_PARAMETERS" in options: options["SOLVER_PARAMETERS"]["sec"] = max( int(options["timeLimit"] / 10), MIN_ITERATION_TIME) else: options["SOLVER_PARAMETERS"] = { "sec": max(int(options["timeLimit"] / 10), MIN_ITERATION_TIME) } else: options["SOLVER_PARAMETERS"] = SOLVER_PARAMETERS model_instance = model.create_instance(data, report_timing=False) opt = SolverFactory("cbc") opt.options.update(options["SOLVER_PARAMETERS"]) self.iterator = BaseIterator(model_instance, opt, verbose=False) status, obj = self.get_initial_solution(step=5, modes_steps=3) log.debug("Solving the complete problem") status, obj = self.iterator.solve() self.status = status self.model_solution = self.iterator.instance log.debug("Status: {} Objective value: {}".format(self.status, obj)) if is_feasible(self.status): if print_file: self.print_instance() data = self.format_solution() self.solution = Solution(data) else: self.solution = Solution({}) return get_status_value(self.status)
def solve(self, options, print_file=False): """ Solve the problem. """ print_file = options.get("print_file", False) debug = log.root.level == log.DEBUG model = get_assign_tasks_model() data = self.get_input_data() # parameters of the resolution. if "SOLVER_PARAMETERS" not in options: options["SOLVER_PARAMETERS"] = {} if "timeLimit" in options: options["SOLVER_PARAMETERS"]["sec"] = options["timeLimit"] else: options["timeLimit"] = SOLVER_PARAMETERS["sec"] log.debug("Max time(s): {}".format(options["timeLimit"])) model_instance = model.create_instance(data, report_timing=True) opt = SolverFactory("cbc") opt.options.update(options["SOLVER_PARAMETERS"]) result = opt.solve(model_instance, tee=debug) self.status = get_status(result) self.model_solution = model_instance if is_feasible(self.status): if print_file: self.print_instance() data = self.format_solution() self.solution = Solution(data) else: self.solution = Solution({}) return get_status_value(self.status)
def solve(self, options, print_file=False): """ Solve the problem. """ model = get_model() data = self.get_input_data() if options is None: options = {} if "timeLimit" in options: if "SOLVER_PARAMETERS" in options: options["SOLVER_PARAMETERS"]["sec"] = options["timeLimit"] else: options["SOLVER_PARAMETERS"] = {"sec": options["timeLimit"]} else: options["SOLVER_PARAMETERS"] = SOLVER_PARAMETERS model_instance = model.create_instance(data, report_timing=False) opt = SolverFactory("cbc") opt.options.update(options["SOLVER_PARAMETERS"]) result = opt.solve(model_instance, tee=False) self.status = get_status(result) self.model_solution = model_instance obj = model_instance.f_obj() print("Status: {} Objective value: {}".format(self.status, obj)) if is_feasible(self.status): if print_file: self.print_instance() data = self.format_solution() self.solution = Solution(data) else: self.solution = Solution({}) return get_status_value(self.status)
def solve(self, options, print_file=False): """ Solve the problem. """ print_file = options.get("print_file", False) debug = log.root.level == log.DEBUG # parameters of the resolution. if "SOLVER_PARAMETERS" not in options: options["SOLVER_PARAMETERS"] = {} if "timeLimit" in options: if "SOLVER_PARAMETERS" in options: options["SOLVER_PARAMETERS"]["sec"] = options["timeLimit"] else: options["SOLVER_PARAMETERS"] = {"sec": options["timeLimit"]} else: options["timeLimit"] = SOLVER_PARAMETERS["sec"] log.debug("Max time(s): ", options["timeLimit"]) dataDict = self.instance.to_dict() listJobs = list(set([j["id"] for j in dataDict["jobs"]])) # First we calculate feasible modes for jobs model_modes = get_feasible_modes() data, max_duration_new_job, mode_max_duration = self.get_input_data( jobsToSolve=len(listJobs)) model_modes_instance = model_modes.create_instance(data) opt = SolverFactory("cbc") opt.options.update(options["SOLVER_PARAMETERS"]) result = opt.solve(model_modes_instance, tee=debug) self.status = get_status(result) self.model_solution = model_modes_instance if not is_feasible(self.status): self.solution = Solution({}) return get_status_value(self.status) for iResource in model_modes_instance.sResources: log.debug( "used", iResource, sum( value(model_modes_instance.v01JobMode[iJob, iMode]) * value(model_modes_instance.pNeeds[iJob, iMode, iResource]) for iJob in model_modes_instance.sJobs for iMode in model_modes_instance.sModes if (iJob, iMode, iResource) in model_modes_instance.pNeeds), "total:", value(model_modes_instance.pAvailability[iResource]), ) for iJob in model_modes_instance.sJobs: for iMode in model_modes_instance.sModes: if (iJob, iMode) in model_modes_instance.pDuration: if value(model_modes_instance.v01JobMode[iJob, iMode]) == 1: log.debug(iJob, iMode) log.debug("time fix model (s):", result.solver.system_time) self.fixed_jobs_modes = { (iJob, iMode): value(model_modes_instance.v01JobMode[iJob, iMode]) for iJob in model_modes_instance.sJobs for iMode in model_modes_instance.sModes if (iJob, iMode) in model_modes_instance.pDuration } # End feasible modes model = get_tasks_fix_modes() log.debug("Starting loop") # Loop for solving the problem for loop_jobs in listJobs: if loop_jobs == 2: # First we solve without warmstart # Get the data data, max_duration_new_job = self.get_input_data_fix_mode( jobsToSolve=loop_jobs) model_instance = model.create_instance(data) opt = SolverFactory("cbc") options["SOLVER_PARAMETERS"] = {"ratio": 0.2} opt.options.update(options["SOLVER_PARAMETERS"]) result = opt.solve(model_instance) end_solve = time.time() self.status = get_status(result) self.model_solution = model_instance if not is_feasible(self.status): self.solution = Solution({}) return get_status_value(self.status) log.debug( "Jobs solved: ", loop_jobs, ", nº Slots:", int(value(model_instance.vMaxSlot)), ", time (s):", result.solver.system_time, ) previous_instance = model_instance aux_periods = 0 elif loop_jobs > 2: # We solve starting with previous solution and add new job # Get the data data, max_duration_new_job = self.get_input_data_fix_mode( jobsToSolve=loop_jobs, previusSlots=aux_periods + value(previous_instance.vMaxSlot), ) if loop_jobs == listJobs[-1]: model_instance = model.create_instance(data) options["SOLVER_PARAMETERS"] = {"ratio": 0.01} opt.options.update(options["SOLVER_PARAMETERS"]) else: model_instance = model.create_instance(data) # Initialize previous solution for j in previous_instance.sJobs: for s in previous_instance.sSlots: if s <= model_instance.sSlots[-1]: model_instance.v01Start[j, s].value = value( previous_instance.v01Start[j, s]) model_instance.v01End[j, s].value = value( previous_instance.v01End[j, s]) model_instance.v01JobDone[j, s].value = value( previous_instance.v01JobDone[j, s]) # model_instance.vMaxSlot.value = value(previous_instance.vMaxSlot) + # Initialize new job, first to 0 for n in range( int(value(previous_instance.vMaxSlot) + 1), int( value(previous_instance.vMaxSlot) + max_duration_new_job + 1), ): model_instance.v01Start[loop_jobs, n].value = 0 model_instance.v01End[loop_jobs, n].value = 0 # Then to 1 only when true model_instance.v01Start[ loop_jobs, int(value(previous_instance.vMaxSlot) + 1)].value = 1 model_instance.v01End[loop_jobs, int( value(previous_instance.vMaxSlot) + max_duration_new_job), ].value = 1 for n in range( int(value(previous_instance.vMaxSlot) + 1), int( value(previous_instance.vMaxSlot) + max_duration_new_job + 1), ): model_instance.v01JobDone[loop_jobs, n].value = 1 # WarmStart write_cbc_warmstart_file("./cbc_warmstart.soln", model_instance, opt) result = opt.solve( model_instance, tee=debug, warmstart=True, warmstart_file="./cbc_warmstart.soln", ) self.status = get_status(result) self.model_solution = model_instance if not is_feasible(self.status): self.solution = Solution({}) return get_status_value(self.status) log.debug( "Jobs solved: ", loop_jobs, ", nº Slots:", int(value(model_instance.vMaxSlot)), ", time (s):", result.solver.system_time, ) previous_instance = model_instance end_solve = time.time() # Solve complete problem with warmstart time_left = options["timeLimit"] - (time.time() - start_time) options["timeLimit"] = time_left log.debug("Time left (s)", time_left) log.debug("Solve complete problem with warmstart") model = get_assign_tasks_model() data, max_duration_new_job, mode_max_duration = self.get_input_data( jobsToSolve=len(listJobs), previusSlots=value(previous_instance.vMaxSlot)) model_instance = model.create_instance(data) # Check input v01Start = dict() v01End = dict() v01JobDone = dict() v01JobMode = dict() # Initialize previous solution for j in previous_instance.sJobs: for s in previous_instance.sSlots: if s <= model_instance.sSlots[-1]: model_instance.v01Start[j, s].value = int( value(previous_instance.v01Start[j, s])) model_instance.v01End[j, s].value = int( value(previous_instance.v01End[j, s])) v01Start[j, s] = int(value(previous_instance.v01Start[j, s])) v01End[j, s] = int(value(previous_instance.v01End[j, s])) for m in model_instance.sModes: if (j, m) in self.fixed_jobs_modes: if self.fixed_jobs_modes[j, m] == 1: model_instance.v01JobDone[j, s, m].value = int( value(previous_instance.v01JobDone[j, s])) model_instance.v01JobMode[j, m].value = 1 v01JobDone[j, s, m] = int( value(previous_instance.v01JobDone[j, s])) v01JobMode[j, m] = 1 # WarmStart opt.options.update(options["SOLVER_PARAMETERS"]) write_cbc_warmstart_file("./cbc_warmstart.soln", model_instance, opt) result = opt.solve( model_instance, tee=debug, warmstart=True, warmstart_file="./cbc_warmstart.soln", ) log.debug( "Jobs solved: ", loop_jobs, ", nº Slots:", int(value(model_instance.vMaxSlot)), ", time (s):", result.solver.system_time, ) log.debug("Finish") self.status = get_status(result) self.model_solution = model_instance log.debug("End of solver. Total time: %.2f seconds" % (time.time() - start_time)) if is_feasible(self.status): if print_file: self.print_instance() data = self.format_solution() self.solution = Solution(data) else: self.solution = Solution({}) return get_status_value(self.status)
def __init__(self, instance, solution=None): if solution is None: solution = Solution({}) super().__init__(instance, solution) self.input_data = {} log.debug("\nSolving with Iterator1")
def __init__(self, instance, solution=None): if solution is None: solution = Solution({}) super().__init__(instance, solution) print("\nSolving with Milp1")
def solve(self, options): """ Solve the problem. """ print_file = options.get("print_file", False) debug = log.root.level == log.DEBUG # parameters of the resolution. if "SOLVER_PARAMETERS" not in options: options["SOLVER_PARAMETERS"] = {} if "timeLimit" in options: options["SOLVER_PARAMETERS"]["sec"] = options["timeLimit"] else: options["timeLimit"] = SOLVER_PARAMETERS["sec"] log.debug("Max time(s): ".format(options["timeLimit"])) model = get_assign_tasks_model() dataDict = self.instance.to_dict() listJobs = list(set([j["id"] for j in dataDict["jobs"]])) log.debug("Starting loop") # Loop for solving the problem for loop_jobs in listJobs: if loop_jobs == 2: # First we solve without warmstart # Get the data data, max_duration_new_job, mode_max_duration = self.get_input_data( jobsToSolve=loop_jobs) model_instance = model.create_instance(data, report_timing=debug) opt = SolverFactory("cbc") options["SOLVER_PARAMETERS"] = {"ratio": 0.2} opt.options.update(options["SOLVER_PARAMETERS"]) result = opt.solve(model_instance, tee=debug) end_solve = time.time() log.debug( "Jobs solved: {}, num Slots: {}, time (s): {}, ".format( loop_jobs, int(value(model_instance.vMaxSlot)), result.solver.system_time, )) previous_instance = model_instance aux_periods = 0 elif loop_jobs > 2: # We solve starting with previous solution and add new job # Get the data data, max_duration_new_job, mode_max_duration = self.get_input_data( jobsToSolve=loop_jobs, previusSlots=aux_periods + value(previous_instance.vMaxSlot), ) if loop_jobs == listJobs[-1]: model_instance = model.create_instance(data) options["SOLVER_PARAMETERS"] = {"ratio": 0.01} opt.options.update(options["SOLVER_PARAMETERS"]) else: model_instance = model.create_instance(data) # Initialize previous solution for j in previous_instance.sJobs: for s in previous_instance.sSlots: if s <= model_instance.sSlots[-1]: for m in previous_instance.sModes: model_instance.v01Start[j, s].value = value( previous_instance.v01Start[j, s]) model_instance.v01End[j, s].value = value( previous_instance.v01End[j, s]) model_instance.v01JobDone[ j, s, m].value = value( previous_instance.v01JobDone[j, s, m]) model_instance.v01JobMode[j, m].value = value( previous_instance.v01JobMode[j, m]) # Initialize new job, first to 0 for n in range( int(value(previous_instance.vMaxSlot) + 1), int( value(previous_instance.vMaxSlot) + max_duration_new_job + 1), ): model_instance.v01Start[loop_jobs, n].value = 0 model_instance.v01End[loop_jobs, n].value = 0 for m in model_instance.sModes: model_instance.v01JobMode[loop_jobs, m].value = 0 # Then to 1 only when true model_instance.v01Start[ loop_jobs, int(value(previous_instance.vMaxSlot) + 1)].value = 1 model_instance.v01End[loop_jobs, int( value(previous_instance.vMaxSlot) + max_duration_new_job), ].value = 1 for n in range( int(value(previous_instance.vMaxSlot) + 1), int( value(previous_instance.vMaxSlot) + max_duration_new_job + 1), ): model_instance.v01JobDone[loop_jobs, n, int(mode_max_duration)].value = 1 model_instance.v01JobMode[loop_jobs, int(mode_max_duration)].value = 1 # WarmStart write_cbc_warmstart_file("./cbc_warmstart.soln", model_instance, opt) result = opt.solve( model_instance, tee=debug, warmstart=True, warmstart_file="./cbc_warmstart.soln", ) log.debug( "Jobs solved: {}, num Slots: {}, time (s): {}, ".format( loop_jobs, int(value(model_instance.vMaxSlot)), result.solver.system_time, )) previous_instance = model_instance # Check non-renawable resources availability: aux_periods = 0 for iResource in model_instance.sResources: if (sum( value(model_instance.v01JobMode[iJob, iMode]) * value(model_instance.pNeeds[iJob, iMode, iResource]) for iJob in model_instance.sJobs for iMode in model_instance.sModes if (iJob, iMode, iResource) in model_instance.pNeeds) / value(model_instance.pAvailability[iResource]) > 0.9 and "N" in iResource): aux_periods = (round( value(previous_instance.vMaxSlot) / loop_jobs) * 2) log.debug("used: {} {}, total: {}".format( iResource, sum( value(model_instance.v01JobMode[iJob, iMode]) * value(model_instance.pNeeds[iJob, iMode, iResource]) for iJob in model_instance.sJobs for iMode in model_instance.sModes if (iJob, iMode, iResource) in model_instance.pNeeds), value(model_instance.pAvailability[iResource]), )) self.status = get_status(result) self.model_solution = model_instance log.debug("End of loop. Total time: %.2f seconds" % (time.time() - start_time)) if is_feasible(self.status): if print_file: self.print_instance() data = self.format_solution() self.solution = Solution(data) else: self.solution = Solution({}) return get_status_value(self.status)
def solve(self, options): model = cp_model.CpModel() input_data = pt.SuperDict.from_dict(self.instance.data) durations_data = pt.SuperDict.from_dict(input_data["durations"]) max_dur_job = durations_data.vapply(lambda v: max(v.values())) horizon = sum(max_dur_job.values()) + 1 jobs_data = input_data["jobs"] needs_data = pt.SuperDict.from_dict(input_data["needs"]) mode_dictionary_to_values = ( lambda v: v.to_tuplist().sorted(key=lambda x: x[0]).take(1) ) # variable declaration: starts = pt.SuperDict( { job: model.NewIntVar(0, horizon, "start_{}".format(job)) for job in jobs_data } ) ends = pt.SuperDict( { job: model.NewIntVar(0, horizon, "end_{}".format(job)) for job in jobs_data } ) job_mode = pt.SuperDict( { job: model.NewIntVar(0, len(modes) - 1, "mode_{}".format(job)) for job, modes in durations_data.items() } ) job_duration_min_max = { job: (min(modes.values()), max(modes.values())) for job, modes in durations_data.items() } job_duration = pt.SuperDict( { job: model.NewIntVar(*bounds, "duration_{}".format(job)) for job, bounds in job_duration_min_max.items() } ) interval = pt.SuperDict( { job: model.NewIntervalVar( starts[job], job_duration[job], ends[job], "interval_{}".format(job) ) for job in jobs_data } ) mode_duration_perjob = durations_data.vapply(mode_dictionary_to_values) # definition of job duration [ model.AddElement( job_mode[job], mode_duration_perjob[job], job_duration[job] ) for job in jobs_data ] # for each job and resource: # an array of consumptions (one per mode in order) needs_data_perjob = ( needs_data.to_dictup() .to_tuplist() .take([0, 2, 1, 3]) .to_dict([2, 3]) .vapply(sorted) .vapply(pt.TupList) .vapply(lambda v: v.take(1)) ) # for each job and resource: # a variable with the consumption job_consumption = needs_data_perjob.kvapply( lambda k, v: model.NewIntVar(min(v), max(v), "consumption_{}_{}".format(*k)) ) # definition of job consumption for (job, res), needs in needs_data_perjob.items(): model.AddElement(job_mode[job], needs, job_consumption[job, res]) # succession needs to be guaranteed for job, job_data in input_data["jobs"].items(): for successor in job_data["successors"]: model.Add(starts[successor] >= ends[job]) # resource usage job_consumption_per_res = ( job_consumption.to_tuplist() .take([1, 0, 2]) .to_dict(2, is_list=False) .to_dictdict() ) for resource, res_data in input_data["resources"].items(): # we get jobs that consume that resource and how much jobs, consumptions = zip(*job_consumption_per_res[resource].items_tl()) relevant_intervals = [interval[j] for j in jobs] if resource in self.instance.get_renewable_resources(): # renewable resources we use intervals to check them model.AddCumulative( intervals=relevant_intervals, demands=consumptions, capacity=res_data["available"], ) else: # non renewable resources we sum all model.Add(sum(consumptions) <= res_data["available"]) # we set the objective as the makespan obj_var = model.NewIntVar(0, horizon, "makespan") model.AddMaxEquality(obj_var, ends.values()) model.Minimize(obj_var) solver = cp_model.CpSolver() solver.parameters.max_time_in_seconds = options.get("timeLimit", 10) status = solver.Solve(model) if status not in [cp_model.OPTIMAL, cp_model.FEASIBLE]: return status start_sol = starts.vapply(solver.Value) mode_sol = job_mode.vapply(lambda v: solver.Value(v) + 1) _func = lambda x, y: dict(period=x, mode=y) solution = start_sol.sapply(func=_func, other=mode_sol) self.solution = Solution(solution) return status