Ejemplo n.º 1
0
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()
Ejemplo n.º 3
0
    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()