def convert(): milp = MILP() milp.problem_type = args.problem_type model = Model() model.hideOutput() heur = LogBestSol() model.includeHeur(heur, "PyHeur", "custom heuristic implemented in python", "Y", timingmask=SCIP_HEURTIMING.BEFORENODE) model.setRealParam('limits/gap', args.gap) model.readProblem(args.inp_file) milp.mip = scip_to_milps(model) model.optimize() heur.done() milp.optimal_objective = model.getObjVal() milp.optimal_solution = { var.name: model.getVal(var) for var in model.getVars() } milp.is_optimal = (model.getStatus() == 'optimal') milp.optimal_sol_metadata.n_nodes = model.getNNodes() milp.optimal_sol_metadata.gap = model.getGap() milp.optimal_sol_metadata.primal_integral = heur.primal_integral milp.optimal_sol_metadata.primal_gaps = heur.l feasible_sol = model.getSols()[-1] milp.feasible_objective = model.getSolObjVal(feasible_sol) milp.feasible_solution = { var.name: model.getSolVal(feasible_sol, var) for var in model.getVars() } model = Model() model.hideOutput() relax_integral_constraints(milp.mip).add_to_scip_solver(model) model.optimize() assert model.getStatus() == 'optimal' milp.optimal_lp_sol = { var.name: model.getVal(var) for var in model.getVars() } return milp
def solve(self, time_limit): ex_model = Model("extensive model") eventhdlr = IP_Eventhdlr() eventhdlr.IPSol = self.best_sol_list x = {} y = {} values = self._instance.get_values() for i in range(len(values)): x[i] = ex_model.addVar(vtype="B", name="x(%s)" % i) for s in range(self._n_w): for i in range(len(values)): y[i, s] = ex_model.addVar(vtype="B", name="y{},{}".format(i, s)) ex_model.addCons(x[i] >= y[i, s], "x,y{},sc:{}".format(i, s)) for s in range(self._n_w): w = self._instance.sample_scenarios() ex_model.addCons( quicksum(w[i] * (x[i] - y[i, s]) for i in range(len(values))) <= self._instance.get_C(), "respect capacity for scenario {}".format(s)) ex_model.setObjective( quicksum(x[i] * values[i] for i in range(len(values))) - (1 / self._n_w) * quicksum( quicksum(y[i, s] * (self._instance.get_penalty() + values[i]) for i in range(len(values))) for s in range(self._n_w)), "maximize") ex_model.data = x, y ex_model.hideOutput() ex_model.includeEventhdlr(eventhdlr, "IPBest_Sol", "retrieve best bound after each LP event") ex_model.setRealParam('limits/time', time_limit) ex_model.optimize() self.gap = ex_model.getGap() status = ex_model.getStatus() if status == "unbounded" or status == "infeasible": return status x, y = ex_model.data self.solution = np.zeros(len(values)) for i in range(len(values)): self.solution[i] = ex_model.getVal(x[i]) self.opt_obj = ex_model.getObjVal()
def get_best_offline(self): start = time.clock() model = Model("offline global optimization") # 如果一个解找到后遍历10000节点仍没有新的,就停止 model.setLongintParam('limits/stallnodes', 10000) # task_choose = Xj, 表示第j个task是否选择被执行 task_choose = {} # schedule_task = Yjl(t), 表示第j个task在第t时间片中是否在第l个cloudlet中执行 schedule_task = {} # inner_battery = Utg, 表示第t个时间片需要的内部电池用电量 inner_battery = 0 # overexceed_time = Tau(j),表示第j个task的超时时长 overexceed_time= {} # w[j] time_need_array = np.zeros(self.task_count, dtype=np.int32) # lambda[j] workload_array = np.zeros(self.task_count, dtype=np.int32) # d[j] deadline_array = np.zeros(self.task_count, dtype=np.int32) # b[j] welfare_array = np.zeros(self.task_count, dtype=np.float64) # f[j] penalty_coeff_array = np.zeros(self.task_count, dtype=np.float64) # a[j] arrive_array = np.zeros(self.task_count, dtype=np.int32) for index, t in enumerate(self.task_list): time_need_array[index] = t.time_need workload_array[index] = t.workload deadline_array[index] = t.deadline welfare_array[index] = t.welfare penalty_coeff_array[index] = t.welfare / (self.end_EDR - t.deadline) arrive_array[index] = t.arrive servers_amount_array = np.zeros(self.cloudlet_count, dtype=np.int32) idle_power_array = np.zeros(self.cloudlet_count, dtype=np.float64) peak_power_array = np.zeros(self.cloudlet_count, dtype=np.float64) PUE_array = np.zeros(self.cloudlet_count, dtype=np.float64) for index, c in enumerate(self.cloudlet_list): servers_amount_array[index] = c.servers_amount idle_power_array[index] = c.idle_power peak_power_array[index] = c.peak_power PUE_array[index] = c.PUE # D' = D - E - T*sum(N[l] * Pidle[l]) * PUE[l] power_threshold = self.original_energy - self.energy_cut - self.end_EDR * sum( l.servers_amount * l.idle_power * l.PUE for l in self.cloudlet_list) # beta[l] = (Peak_power[l] - Idle_power[l]) * PUE[l] power_range_array = (peak_power_array - idle_power_array) * PUE_array # p 表示本地用电的单位价格 inner_power_percost = 0.32 # 这里的一些命名规范完全参考论文中的model for j in range(self.task_count): task_choose[j] = model.addVar(vtype='B', name='X[%d]' % j) overexceed_time[j] = model.addVar(vtype='I', lb=0.0, ub=self.end_EDR-deadline_array[j]-1, name='Tau[%d]' % j) for l in range(self.cloudlet_count): for t in range(arrive_array[j], self.end_EDR): schedule_task[j, l, t] = model.addVar(vtype='B', name='Y[%d, %d, %d]' % (j, l, t)) inner_battery = model.addVar(vtype='C', lb=0.0, name='Ug') # 以下为model约束条件 for t in range(self.end_EDR): for l in range(self.cloudlet_count): model.addCons(cons=(quicksum(workload_array[j] * schedule_task[j, l, t] for j in range(self.task_count) if (j, l, t) in schedule_task) <= servers_amount_array[l]), name='3a constrain') for j in range(self.task_count): for t in range(arrive_array[j], self.end_EDR): model.addCons(cons=(quicksum(schedule_task[j, l, t] for l in range(self.cloudlet_count)) <= 1), name='3d constrain') for j in range(self.task_count): for t in range(arrive_array[j], self.end_EDR): model.addCons(cons=(t * quicksum(schedule_task[j, l, t] for l in range(self.cloudlet_count)) <= deadline_array[j] + overexceed_time[j]), name='3c constrain') for j in range(self.task_count): model.addCons(cons=(time_need_array[j] * task_choose[j] == quicksum(schedule_task[j, l, t] for l in range(self.cloudlet_count) for t in range(arrive_array[j], self.end_EDR))), name='3e constrain') model.addCons(cons=(quicksum(power_range_array[l] * workload_array[j] * schedule_task[j, l, t] for j in range(self.task_count) for l in range(self.cloudlet_count) for t in range(arrive_array[j], self.end_EDR)) <= power_threshold + inner_battery), name='3b constrain') # 这里没有考虑pi, p, theta_i的值!!! model.setObjective(coeffs=(quicksum((welfare_array[j] * task_choose[j]) - (penalty_coeff_array[j] * overexceed_time[j]) for j in range(self.task_count)) - inner_power_percost * inner_battery), sense='maximize') model.optimize() end = time.clock() # 显示最优解的相关信息 cloudlet_counter = Counter() # 统计每个时间片内的耗电量 electricity_counter = Counter() # 每个时间片t内都至少有所有cloudlet空耗的电量 for t in range(self.end_EDR): electricity_counter[t] += sum(l.servers_amount * l.idle_power * l.PUE for l in self.cloudlet_list) accepted_task_count = 0 schedule_output = str() for j in range(self.task_count): X_j = int(round(model.getVal(task_choose[j]))) Tau_j = int(round(model.getVal(overexceed_time[j]))) if X_j == 1: accepted_task_count += 1 schedule_output += "X[%d] = 1\n" % j schedule_output += "Tau[%d] = %d\n" % (j, Tau_j) cur_arrive = self.task_list[j].arrive cur_deadline = self.task_list[j].deadline for t in range(cur_arrive, cur_deadline + Tau_j + 1): for l in range(self.cloudlet_count): Y_jlt = model.getVal(schedule_task[j, l, t]) # print(Y_jlt) if int(round(Y_jlt)) == 1: schedule_output += "(cloudlet %d at time %d)" % (l, t) cloudlet_counter[l] += 1 electricity_counter[t] += power_range_array[l] * self.task_list[j].workload schedule_output += "\n\n" self.offline_solution["optimal"] = model.getObjVal() self.offline_solution["accepted_rate"] = accepted_task_count / self.task_count self.offline_solution["execute_time"] = end - start self.offline_solution["Ug"] = model.getVal(inner_battery) self.offline_solution["cloudlet_counter"] = cloudlet_counter.most_common() self.offline_solution["electricity_counter"] = electricity_counter.values() self.offline_solution["primal-dual gap"] = model.getGap()