def obtain_overall_costs(self, edge_selections):
        """
        ============================= [copy from offloading_common.py] =============================
        Calculate the overall costs, which is the sum of cost of each mobile device.

        :param edge_selections: the edge selection decisions for all mobile devices
        :return: overall costs
        """
        parameter = self.get_parameter()
        overall_costs = 0
        for i in range(parameter.get_user_num()):
            if parameter.get_task_requests()[i] == 1:
                division = int(sum(edge_selections[i]))
                if division:
                    # cost = self.obtain_time_consumption(
                    #     division, edge_selections[i], parameter.get_connectable_gains[i])
                    transmit_times = ToolFunction.obtain_transmit_times(
                        division, edge_selections[i], parameter,
                        parameter.get_connectable_gains()[i])
                    edge_exe_times = ToolFunction.obtain_edge_exe_times(
                        division, parameter)
                    edge_times = transmit_times + edge_exe_times
                    cost = max(edge_times) + parameter.get_local_exe_time(
                    ) + parameter.get_coordinate_cost() * division
                else:
                    cost = parameter.get_drop_penalty()
            else:
                cost = 0
            overall_costs += cost
        return overall_costs
    def obtain_time_consumption(self, division, edge_selection,
                                channel_power_gains):
        """
        Calculate the time consumption on transmission and edge execution for one mobile device.

        :param division: the number of chosen edge sites (not zero)
        :param edge_selection: the edge selection decision of one mobile devices
        :param channel_power_gains: the channel power gains of one mobile devices to every connectable servers
        :return: the time consumption on transmission and edge execution
        """
        parameter = self.get_parameter()
        transmit_times = ToolFunction.obtain_transmit_times(
            division, edge_selection, parameter, channel_power_gains)
        edge_exe_times = ToolFunction.obtain_edge_exe_times(
            division, parameter)
        edge_times = transmit_times + edge_exe_times
        time_consumption = max(edge_times) + parameter.get_local_exe_time(
        ) + parameter.get_coordinate_cost() * division
        return time_consumption
Пример #3
0
    def obtain_overall_costs(self, parameter):
        """
        Calculate the overall costs, which is the sum of cost of each mobile device.

        :param parameter: the instance of class Parameter
        :return: overall costs
        """
        overall_costs = 0
        for i in range(self.__user_num):
            transmit_times = ToolFunction.obtain_transmit_times(
                self.edge_selections[i], parameter,
                self.__connectable_distances[i])
            edge_exe_times = ToolFunction.obtain_edge_exe_times(
                self.edge_selections[i], parameter)
            edge_times = transmit_times + edge_exe_times
            division = sum(self.edge_selections[i])
            is_dropped = False if division else True
            overall_cost = max(edge_times) + parameter.get_local_exe_time() + parameter.get_coordinate_cost() * \
                           sum(self.edge_selections[i]) + is_dropped * parameter.get_drop_penalty()
            overall_costs += overall_cost
        return overall_costs
    def obtain_overall_costs(self, parameter):
        """
        Calculate 'V * overall_costs + Lyapunov_drift', which is the sum of it of each mobile device.

        :param parameter: the instance of class Parameter
        :return: V * overall costs + \Delta(\Theta)
        """
        overall_costs = 0
        for i in range(len(self.edge_selections)):
            transmit_times = ToolFunction.obtain_transmit_times(
                self.edge_selections[i], parameter,
                self.__connectable_distances[i])
            edge_exe_times = ToolFunction.obtain_edge_exe_times(
                self.edge_selections[i], parameter)
            edge_times = transmit_times + edge_exe_times
            division = sum(self.edge_selections[i])
            is_dropped = False if division else True
            overall_cost = max(edge_times) + parameter.get_local_exe_time() + parameter.get_coordinate_cost() * \
                           sum(self.edge_selections[i]) + is_dropped * parameter.get_drop_penalty()
            neg_lyapunov_drift = (parameter.get_local_exe_energy() + ToolFunction.obtain_transmit_energys(
                self.edge_selections[i], parameter, self.get_connectable_distances()[i])) * \
                             self.get_virtual_energy_levels()[i]
            overall_costs += overall_cost - neg_lyapunov_drift
        return overall_costs
    def generate_from_pos_ins(self, pos_instance):
        """
        Generate an instance from an exist positive instance.

        :param pos_instance: the exist positive instance
        :return: a feasible instance
        """
        parameter = self.get_parameter()
        assignable_nums = np.repeat(parameter.get_max_assign(),
                                    parameter.get_server_num())
        edge_selections = self.greedy_sample(assignable_nums)
        ins_features = []
        for i in range(parameter.get_user_num()):
            if parameter.get_task_requests()[i] == 1:
                division = int(sum(edge_selections[i]))
                if division:
                    times = self.obtain_time_consumption(
                        division, edge_selections[i],
                        parameter.get_connectable_gains()[i])
                    energys = ToolFunction.obtain_transmit_energy(
                        division, edge_selections[i], parameter,
                        parameter.get_connectable_gains()[i])
                    # satisfy the constraint
                    if times >= parameter.get_ddl(
                    ) or energys > self.__battery_energy_levels[i]:
                        edge_selections[i] = np.zeros(len(edge_selections[i]))
                else:
                    pass
                for j in range(len(edge_selections[i])):
                    ins_features.append(edge_selections[i][j])
        dimension = Dimension(parameter.get_dim_size())
        instance = Instance(dimension)
        instance.set_features(ins_features)

        # update from the chosen positive instance
        for i in range(len(instance.get_features())):
            if self.get_labels()[i]:
                instance.set_feature(i, pos_instance.get_feature(i))

        # re-check whether the maximum assignable nums is satisfied
        edge_selections = self.instance_to_edge_selections(instance)
        for j in range(parameter.get_server_num()):
            if assignable_nums[j] >= len(parameter.get_connectable_users()[j]):
                continue
            connect_users = []
            for i in range(len(parameter.get_connectable_users()[j])):
                user_idx = parameter.get_connectable_users()[j][i]
                edge_idx = list.index(
                    parameter.get_connectable_servers()[user_idx], j)
                if edge_selections[user_idx][edge_idx] == 1:
                    connect_users.append(user_idx)
            if len(connect_users) <= assignable_nums[j]:
                continue
            permitted_connect_users = random.sample(connect_users,
                                                    assignable_nums[j])
            non_permitted = [
                u for u in connect_users if u not in permitted_connect_users
            ]
            for i in range(len(non_permitted)):
                user_idx = non_permitted[i]
                edge_idx = list.index(
                    parameter.get_connectable_servers()[user_idx], j)
                edge_selections[user_idx][edge_idx] = 0

        # re-check whether the ddl and energy consumption are satisfied
        for i in range(parameter.get_user_num()):
            if parameter.get_task_requests()[i] == 1:
                division = int(sum(edge_selections[i]))
                if division:
                    # times = self.obtain_time_consumption(division, edge_selections[i],
                    #                                      parameter.get_connectable_gains()[i])
                    transmit_times = ToolFunction.obtain_transmit_times(
                        division, edge_selections[i], parameter,
                        parameter.get_connectable_gains()[i])
                    edge_exe_times = ToolFunction.obtain_edge_exe_times(
                        division, parameter)
                    edge_times = transmit_times + edge_exe_times
                    times = max(edge_times) + parameter.get_local_exe_time() + \
                        parameter.get_coordinate_cost() * division
                    energys = ToolFunction.obtain_transmit_energy(
                        division, edge_selections[i], parameter,
                        parameter.get_connectable_gains()[i])
                    # satisfy the constraint
                    if times >= parameter.get_ddl(
                    ) or energys > self.__battery_energy_levels[i]:
                        edge_selections[i] = np.zeros(len(edge_selections[i]))
                else:
                    pass

        # get final instance from the new edge_selections
        ins_features = []
        for i in range(parameter.get_user_num()):
            if parameter.get_task_requests()[i] == 1:
                for j in range(len(edge_selections[i])):
                    ins_features.append(edge_selections[i][j])
        instance.set_features(ins_features)
        return instance