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
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