Пример #1
0
    def embedding(self, VNRs_COLLECTED, COPIED_SUBSTRATE, action):
        sorted_vnrs = sorted(VNRs_COLLECTED.values(),
                             key=lambda vnr: vnr.revenue,
                             reverse=True)

        for vnr in sorted_vnrs:
            original_copied_substrate = copy.deepcopy(COPIED_SUBSTRATE)

            s_nodes_combinations = self.find_substrate_nodes_combinations(
                vnr, COPIED_SUBSTRATE)

            assert original_copied_substrate == COPIED_SUBSTRATE

            if s_nodes_combinations is None:
                action.vnrs_postponement[vnr.id] = vnr
                continue

            early_stopping = GAEarlyStopping(
                patience=config.STOP_PATIENCE_COUNT,
                verbose=True,
                delta=0.0001,
                copied_substrate=COPIED_SUBSTRATE)

            multi_ga_operator = MultiGAOperator(vnr, s_nodes_combinations,
                                                COPIED_SUBSTRATE)

            ### INITIALIZE ###
            is_ok = multi_ga_operator.initialize()

            if not is_ok:
                self.num_link_embedding_fails += 1

                msg = "VNR {0} REJECTED ({1}): 'no suitable LINK for bandwidth demand: {2}}".format(
                    vnr.id, self.num_link_embedding_fails, vnr)

                self.logger.info("{0} {1}".format(
                    utils.step_prefix(self.time_step), msg))
                action.vnrs_postponement[vnr.id] = vnr
                continue

            multi_ga_operator.process()
            expected_generation = 1
            while True:
                if multi_ga_operator.is_all_one_generation_finished(
                        expected_generation=expected_generation):
                    multi_ga_operator.evaluate_all_results_from_workers()

                    solved, _ = early_stopping.evaluate(
                        elite=multi_ga_operator.elite,
                        evaluation_value=multi_ga_operator.elite.fitness)

                    if solved:
                        break

                    multi_ga_operator.go_next_generation()
                    expected_generation += 1

                time.sleep(0.1)

            assert original_copied_substrate == COPIED_SUBSTRATE
Пример #2
0
    def complete_vnrs_serving(self):
        '''
        processing of serving_completed
        :return: vnrs_serving_completed
        '''
        vnrs_serving_completed = []
        for vnr, embedding_s_nodes, embedding_s_paths in self.VNRs_SERVING.values(
        ):
            if vnr.time_step_serving_completed and vnr.time_step_serving_completed <= self.time_step:
                vnrs_serving_completed.append(vnr)

                for s_node_id, v_cpu_demand in embedding_s_nodes.values():
                    self.SUBSTRATE.net.nodes[s_node_id]['CPU'] += v_cpu_demand

                for s_links_in_path, v_bandwidth_demand in embedding_s_paths.values(
                ):
                    for s_link in s_links_in_path:
                        self.SUBSTRATE.net.edges[s_link][
                            'bandwidth'] += v_bandwidth_demand

        for vnr in vnrs_serving_completed:
            assert vnr.id in self.VNRs_SERVING
            del self.VNRs_SERVING[vnr.id]
            if self.logger:
                self.logger.info("{0} VNR SERVING COMPLETED {1}".format(
                    utils.step_prefix(self.time_step), vnr))

        return vnrs_serving_completed
Пример #3
0
 def collect_vnrs_new_arrival(self):
     for vnr in self.VNRs_INFO.values():
         if vnr.time_step_arrival == self.time_step:
             self.VNRs_COLLECTED[vnr.id] = vnr
             self.total_arrival_vnrs += 1
             if self.logger:
                 self.logger.info("{0} NEW VNR ARRIVED {1}".format(
                     utils.step_prefix(self.time_step), vnr))
Пример #4
0
    def find_substrate_path(self, copied_substrate, vnr, embedding_s_nodes):
        embedding_s_paths = {}
        directed_copied_substrate = copied_substrate.net.to_directed()

        # mapping the virtual nodes and substrate_net nodes
        for src_v_node, dst_v_node, edge_data in vnr.net.edges(data=True):
            v_link = (src_v_node, dst_v_node)
            src_s_node = embedding_s_nodes[src_v_node][0]
            dst_s_node = embedding_s_nodes[dst_v_node][0]
            v_bandwidth_demand = edge_data['bandwidth']

            if src_s_node == dst_s_node:
                s_links_in_path = []
                embedding_s_paths[v_link] = (s_links_in_path, v_bandwidth_demand)
            else:
                subnet = nx.subgraph_view(
                    copied_substrate.net,
                    filter_edge=lambda node_1_id, node_2_id: \
                        True if copied_substrate.net.edges[(node_1_id, node_2_id)][
                                    'bandwidth'] >= v_bandwidth_demand else False
                )

                # Just for assertion
                # for u, v, a in subnet.edges(data=True):
                #     assert a["bandwidth"] >= v_bandwidth_demand

                if len(subnet.edges) == 0 or not nx.has_path(subnet, source=src_s_node, target=dst_s_node):
                    self.num_link_embedding_fails += 1
                    msg = "VNR {0} REJECTED ({1}): 'no suitable LINK for bandwidth demand: {2} {3}".format(
                        vnr.id, self.num_link_embedding_fails, v_bandwidth_demand, vnr
                    )
                    self.logger.info("{0} {1}".format(utils.step_prefix(self.time_step), msg))
                    return None

                MAX_K = 1

                # shortest_s_path = utils.k_shortest_paths(subnet, source=src_s_node, target=dst_s_node, k=MAX_K)[0]
                # https://networkx.org/documentation/stable//reference/algorithms/generated/networkx.algorithms.flow.shortest_augmenting_path.html
                residual_network = shortest_augmenting_path(directed_copied_substrate, src_s_node, dst_s_node,
                                                            capacity='bandwidth',
                                                            cutoff=v_bandwidth_demand)
                s_links_in_path = []
                path = []
                for src_r_node, dst_r_node, r_edge_data in residual_network.edges(data=True):
                    if r_edge_data['flow'] > 0:
                        s_links_in_path.append((src_r_node, dst_r_node))

                # s_links_in_path = []
                # for node_idx in range(len(shortest_s_path) - 1):
                #     s_links_in_path.append((shortest_s_path[node_idx], shortest_s_path[node_idx + 1]))

                for s_link in s_links_in_path:
                    # assert copied_substrate.net.edges[s_link]['bandwidth'] >= v_bandwidth_demand
                    copied_substrate.net.edges[s_link]['bandwidth'] -= v_bandwidth_demand

                embedding_s_paths[v_link] = (s_links_in_path, v_bandwidth_demand)

        return embedding_s_paths
Пример #5
0
    def find_substrate_nodes(self, copied_substrate, vnr):
        subset_S_per_v_node = {}
        embedding_s_nodes = {}
        already_embedding_s_nodes = []
        current_embedding_s_nodes = [0] * len(copied_substrate.net.nodes)

        # self.config.TYPE_OF_VIRTUAL_NODE_RANKING.TYPE_2
        sorted_v_nodes_with_node_ranking = utils.get_sorted_v_nodes_with_node_ranking(
            vnr=vnr, type_of_node_ranking=self.type_of_virtual_node_ranking)

        num_remain_v_node = 1
        for v_node_id, v_node_data, _ in sorted_v_nodes_with_node_ranking:
            v_cpu_demand = v_node_data['CPU']
            v_node_location = v_node_data['LOCATION']
            v_pending = len(
                sorted_v_nodes_with_node_ranking) - num_remain_v_node

            # Find the subset S of substrate nodes that satisfy restrictions and
            # available CPU capacity (larger than that specified by the request.)
            subset_S_per_v_node[
                v_node_id] = utils.find_subset_S_for_virtual_node(
                    copied_substrate, v_cpu_demand, v_node_location,
                    already_embedding_s_nodes)

            # Generate the state
            substrate_features, edge_index, vnr_features = self.get_state_information(
                copied_substrate, vnr, current_embedding_s_nodes, v_node_id,
                v_cpu_demand, v_pending)

            # select the node
            selected_s_node_id = self.a3c_gcn_agent.select_node(
                substrate_features, edge_index, vnr_features)

            if copied_substrate.net.nodes[selected_s_node_id]['CPU'] <= v_cpu_demand or \
                    selected_s_node_id in already_embedding_s_nodes:
                self.num_node_embedding_fails += 1
                msg = "VNR {0} REJECTED ({1}): 'no suitable SUBSTRATE NODE for nodal constraints: {2}' {3}".format(
                    vnr.id, self.num_node_embedding_fails, v_cpu_demand, vnr)
                self.logger.info("{0} {1}".format(
                    utils.step_prefix(self.time_step), msg))
                return None

            assert selected_s_node_id != -1
            embedding_s_nodes[v_node_id] = (selected_s_node_id, v_cpu_demand)

            if not self.allow_embedding_to_same_substrate_node:
                already_embedding_s_nodes.append(selected_s_node_id)

            assert copied_substrate.net.nodes[selected_s_node_id][
                'CPU'] >= v_cpu_demand
            copied_substrate.net.nodes[selected_s_node_id][
                'CPU'] -= v_cpu_demand
            current_embedding_s_nodes[selected_s_node_id] = 1
            num_remain_v_node += 1

        return embedding_s_nodes
Пример #6
0
    def release_vnrs_expired_from_collected(self, vnrs_embedding):
        '''
        processing of leave_from_queue

        :return: vnrs_left_from_queue
        '''
        vnrs_left_from_queue = []
        for vnr in self.VNRs_COLLECTED.values():
            if vnr.time_step_leave_from_queue <= self.time_step and vnr.id not in vnrs_embedding:
                vnrs_left_from_queue.append(vnr)

        for vnr in vnrs_left_from_queue:
            del self.VNRs_COLLECTED[vnr.id]
            if self.logger:
                self.logger.info("{0} VNR LEFT OUT {1}".format(
                    utils.step_prefix(self.time_step), vnr))

        return vnrs_left_from_queue
Пример #7
0
    def find_substrate_nodes_combinations(self, vnr, COPIED_SUBSTRATE):
        sorted_v_nodes_with_node_ranking = utils.get_sorted_v_nodes_with_node_ranking(
            vnr=vnr,
            type_of_node_ranking=config.TYPE_OF_VIRTUAL_NODE_RANKING.TYPE_2)

        #print(sorted_v_nodes_with_node_ranking, "!!!!!")

        all_combinations = []

        self.make_top_n_combinations(
            sorted_v_nodes_with_node_ranking=sorted_v_nodes_with_node_ranking,
            idx=0,
            combination=[],
            all_combinations=all_combinations,
            copied_substrate=COPIED_SUBSTRATE,
            already_embedding_s_nodes=[])

        print("TOTAL {0} combinations".format(len(all_combinations)))
        # for idx, combination in enumerate(all_combinations):
        #     print(idx, combination)

        s_nodes_combinations = []
        for combination_idx, combination in enumerate(all_combinations):
            if len(combination) != len(sorted_v_nodes_with_node_ranking):
                self.num_node_embedding_fails += 1
                msg = "VNR {0} REJECTED ({1}): 'no suitable SUBSTRATE NODE for nodal constraints' {2}".format(
                    vnr.id, self.num_node_embedding_fails, vnr)
                self.logger.info("{0} {1}".format(
                    utils.step_prefix(self.time_step), msg))
                return None

            #print(vnr.id, combination_idx, combination)

            embedding_s_nodes = {}
            for idx, selected_s_node_id in enumerate(combination):
                v_node_id = sorted_v_nodes_with_node_ranking[idx][0]
                v_cpu_demand = sorted_v_nodes_with_node_ranking[idx][1]['CPU']
                embedding_s_nodes[v_node_id] = (selected_s_node_id,
                                                v_cpu_demand)

            s_nodes_combinations.append(embedding_s_nodes)

        return s_nodes_combinations
Пример #8
0
    def find_substrate_nodes(self, copied_substrate, vnr):
        subset_S_per_v_node = {}
        embedding_s_nodes = {}
        already_embedding_s_nodes = []

        for v_node_id, v_node_data in vnr.net.nodes(data=True):
            v_cpu_demand = v_node_data['CPU']
            v_node_location = v_node_data['LOCATION']

            # Find the subset S of substrate nodes that satisfy restrictions and
            # available CPU capacity (larger than that specified by the request.)
            subset_S_per_v_node[
                v_node_id] = utils.find_subset_S_for_virtual_node(
                    copied_substrate, v_cpu_demand, v_node_location,
                    already_embedding_s_nodes)

            selected_s_node_id = max(subset_S_per_v_node[v_node_id],
                                     key=lambda s_node_id: copied_substrate.net
                                     .nodes[s_node_id]['CPU'] - v_cpu_demand,
                                     default=None)

            if selected_s_node_id is None:
                self.num_node_embedding_fails += 1
                msg = "VNR {0} REJECTED ({1}): 'no suitable SUBSTRATE NODE for nodal constraints: {2}' {3}".format(
                    vnr.id, self.num_node_embedding_fails, v_cpu_demand, vnr)
                self.logger.info("{0} {1}".format(
                    utils.step_prefix(self.time_step), msg))
                return None

            assert selected_s_node_id != -1
            embedding_s_nodes[v_node_id] = (selected_s_node_id, v_cpu_demand)

            if not config.ALLOW_EMBEDDING_TO_SAME_SUBSTRATE_NODE:
                already_embedding_s_nodes.append(selected_s_node_id)

            assert copied_substrate.net.nodes[selected_s_node_id][
                'CPU'] >= v_cpu_demand
            copied_substrate.net.nodes[selected_s_node_id][
                'CPU'] -= v_cpu_demand

        return embedding_s_nodes
Пример #9
0
    def starting_serving_for_a_vnr(self, vnr, embedding_s_nodes,
                                   embedding_s_paths):
        for s_node_id, v_cpu_demand in embedding_s_nodes.values():
            self.SUBSTRATE.net.nodes[s_node_id]['CPU'] -= v_cpu_demand

        for s_links_in_path, v_bandwidth_demand in embedding_s_paths.values():
            for s_link in s_links_in_path:
                self.SUBSTRATE.net.edges[s_link][
                    'bandwidth'] -= v_bandwidth_demand

        vnr.time_step_serving_started = self.time_step
        vnr.time_step_serving_completed = self.time_step + vnr.duration
        vnr.cost = utils.get_cost_VNR(vnr, embedding_s_paths)

        self.VNRs_SERVING[vnr.id] = (vnr, embedding_s_nodes, embedding_s_paths)
        if self.logger:
            self.logger.info("{0} VNR SERVING STARTED {1}".format(
                utils.step_prefix(self.time_step), vnr))
        self.total_embedded_vnrs += 1

        del self.VNRs_COLLECTED[vnr.id]
Пример #10
0
    def find_substrate_nodes(self, copied_substrate, vnr):
        '''
        Execute Step 1
        :param copied_substrate: copied substrate network
        :param vnr: virtual network request
        :return: embedded substrate nodesƒ
        '''
        subset_S_per_v_node = {}
        embedding_s_nodes = {}
        already_embedding_s_nodes = []

        # config.TYPE_OF_VIRTUAL_NODE_RANKING.TYPE_2
        sorted_v_nodes_with_node_ranking = utils.get_sorted_v_nodes_with_node_ranking(
            vnr=vnr, type_of_node_ranking=self.type_of_virtual_node_ranking)

        for v_node_id, v_node_data, _ in sorted_v_nodes_with_node_ranking:
            v_cpu_demand = v_node_data['CPU']
            v_node_location = v_node_data['LOCATION']

            # Find the subset S of substrate nodes that satisfy restrictions and
            # available CPU capacity (larger than that specified by the request.)
            subset_S_per_v_node[
                v_node_id] = utils.find_subset_S_for_virtual_node(
                    copied_substrate, v_cpu_demand, v_node_location,
                    already_embedding_s_nodes)

            # if len(subset_S_per_v_node[v_node_id]) == 0:
            #     self.num_node_embedding_fails += 1
            #     msg = "VNR {0} REJECTED ({1}): 'no subset S' - {2}".format(vnr.id, self.num_node_embedding_fails, vnr)
            #     self.logger.info("{0} {1}".format(utils.step_prefix(self.time_step), msg))
            #     return None

            # max_node_ranking = -1.0 * 1e10
            # selected_s_node_id = -1

            selected_s_node_id = max(
                subset_S_per_v_node[v_node_id],
                key=lambda s_node_id: self.calculate_node_ranking(
                    copied_substrate.net.nodes[s_node_id]['CPU'],
                    copied_substrate.net[s_node_id]),
                default=None)

            if selected_s_node_id is None:
                self.num_node_embedding_fails += 1
                msg = "VNR {0} REJECTED ({1}): 'no suitable SUBSTRATE NODE for nodal constraints: {2}' {3}".format(
                    vnr.id, self.num_node_embedding_fails, v_cpu_demand, vnr)
                self.logger.info("{0} {1}".format(
                    utils.step_prefix(self.time_step), msg))
                return None

            # for s_node_id in subset_S_per_v_node[v_node_id]:
            #     node_ranking = self.calculate_node_ranking(
            #         copied_substrate.net.nodes[s_node_id]['CPU'],
            #         copied_substrate.net[s_node_id]
            #     )
            #
            #     if node_ranking > max_node_ranking:
            #         max_node_ranking = node_ranking
            #         selected_s_node_id = s_node_id

            assert selected_s_node_id != -1
            embedding_s_nodes[v_node_id] = (selected_s_node_id, v_cpu_demand)
            if not self.allow_embedding_to_same_substrate_node:
                already_embedding_s_nodes.append(selected_s_node_id)

            assert copied_substrate.net.nodes[selected_s_node_id][
                'CPU'] >= v_cpu_demand
            copied_substrate.net.nodes[selected_s_node_id][
                'CPU'] -= v_cpu_demand

        return embedding_s_nodes
Пример #11
0
    def find_substrate_nodes(self, copied_substrate, vnr):
        '''
        Execute Step 1
        :param copied_substrate: copied substrate network
        :param vnr: virtual network request
        :return: embedded substrate nodes
        '''
        subset_S_per_v_node = {}
        embedding_s_nodes = {}
        already_embedding_s_nodes = []

        # Generate the augmented substrate network with location info.
        self.change_to_augmented_substrate(copied_substrate, vnr,
                                           self.substrate_nodes)

        opt_lp_f_vars, opt_lp_x_vars = self.calculate_LP_variables(
            copied_substrate, vnr)

        for v_node_id, v_node_data in vnr.net.nodes(data=True):
            v_cpu_demand = v_node_data['CPU']
            v_node_location = v_node_data['LOCATION']

            # Find the subset S of substrate nodes that satisfy restrictions and
            # available CPU capacity (larger than that specified by the request.)
            subset_S_per_v_node[
                v_node_id] = utils.find_subset_S_for_virtual_node(
                    copied_substrate, v_cpu_demand, v_node_location,
                    already_embedding_s_nodes)

            selected_s_node_p_value = []
            candidate_s_node_id = []
            selected_s_node_id = max(
                subset_S_per_v_node[v_node_id],
                key=lambda s_node_id: sum(opt_lp_f_vars[
                    (opt_lp_f_vars['u'] == s_node_id) &
                    (opt_lp_f_vars['v'] == v_node_id + self.substrate_nodes)
                ]['solution_value'].values + opt_lp_f_vars[
                    (opt_lp_f_vars['u'] == v_node_id + self.substrate_nodes) &
                    (opt_lp_f_vars['v'] == s_node_id)][
                        'solution_value'].values) * opt_lp_x_vars[
                            (opt_lp_x_vars['u'] == s_node_id) &
                            (opt_lp_x_vars['v'] == v_node_id + self.
                             substrate_nodes)]['solution_value'].values,
                default=None)

            # for calculating p_value
            # selected_s_node_p_value = []
            # candidate_s_node_id = []
            # for s_node_id in subset_S_per_v_node[v_node_id]:
            #     candidate_s_node_id.append(s_node_id)
            #     selected_s_node_p_value.append(
            #         sum(opt_lp_f_vars[
            #                 (opt_lp_f_vars['u'] == s_node_id) &
            #                 (opt_lp_f_vars['v'] == v_node_id + self.substrate_nodes)]['solution_value'].values +
            #             opt_lp_f_vars[
            #                 (opt_lp_f_vars['u'] == v_node_id + self.substrate_nodes) &
            #                 (opt_lp_f_vars['v'] == s_node_id)]['solution_value'].values))

            # Calculate the probability
            # scipy softmax 추가하여 이용하기
            # https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.softmax.html
            total_p_value = sum(selected_s_node_p_value)
            if total_p_value == 0:
                self.num_node_embedding_fails += 1
                msg = "VNR {0} REJECTED ({1}): 'no suitable SUBSTRATE NODE for nodal constraints: {2}' {3}".format(
                    vnr.id, self.num_node_embedding_fails, v_cpu_demand, vnr)
                self.logger.info("{0} {1}".format(
                    utils.step_prefix(self.time_step), msg))
                self.revoke_from_augmented_substrate(copied_substrate, vnr,
                                                     self.substrate_nodes)
                return None
            else:
                probability = softmax(selected_s_node_p_value)
                selected_s_node_id = np.random.choice(candidate_s_node_id,
                                                      p=probability)

            if selected_s_node_id is None:
                self.num_node_embedding_fails += 1
                msg = "VNR {0} REJECTED ({1}): 'no suitable SUBSTRATE NODE for nodal constraints: {2}' {3}".format(
                    vnr.id, self.num_node_embedding_fails, v_cpu_demand, vnr)
                self.logger.info("{0} {1}".format(
                    utils.step_prefix(self.time_step), msg))
                self.revoke_from_augmented_substrate(copied_substrate, vnr,
                                                     self.substrate_nodes)
                return None

            assert selected_s_node_id != -1
            embedding_s_nodes[v_node_id] = (selected_s_node_id, v_cpu_demand)
            if not self.allow_embedding_to_same_substrate_node:
                already_embedding_s_nodes.append(selected_s_node_id)

            assert copied_substrate.net.nodes[selected_s_node_id][
                'CPU'] >= v_cpu_demand
            copied_substrate.net.nodes[selected_s_node_id][
                'CPU'] -= v_cpu_demand

        self.revoke_from_augmented_substrate(copied_substrate, vnr,
                                             self.substrate_nodes)
        return embedding_s_nodes
Пример #12
0
    def find_substrate_nodes(self, copied_substrate, vnr):
        '''
        Execute Step 1
        :param copied_substrate: copied substrate network
        :param vnr: virtual network request
        :return: embedded substrate nodes
        '''
        subset_S_per_v_node = {}
        embedding_s_nodes = {}
        already_embedding_s_nodes = []

        # Generate the augmented substrate network with location info.
        self.change_to_augmented_substrate(copied_substrate, vnr, self.substrate_nodes)

        opt_lp_f_vars, opt_lp_x_vars = self.calculate_LP_variables(copied_substrate, vnr)

        for v_node_id, v_node_data in vnr.net.nodes(data=True):
            v_cpu_demand = v_node_data['CPU']
            v_node_location = v_node_data['LOCATION']

            # Find the subset S of substrate nodes that satisfy restrictions and
            # available CPU capacity (larger than that specified by the request.)
            subset_S_per_v_node[v_node_id] = utils.find_subset_S_for_virtual_node(
                copied_substrate, v_cpu_demand, v_node_location, already_embedding_s_nodes
            )

            # selected_s_node_id = max(
            #     subset_S_per_v_node[v_node_id],
            #     key=lambda s_node_id:
            #         sum(opt_lp_f_vars[(opt_lp_f_vars['u'] == s_node_id) &
            #                           (opt_lp_f_vars['v'] == v_node_id + self.substrate_nodes)]['solution_value'].values +
            #             opt_lp_f_vars[(opt_lp_f_vars['u'] == v_node_id + self.substrate_nodes) &
            #                           (opt_lp_f_vars['v'] == s_node_id)]['solution_value'].values
            #             ) *
            #         opt_lp_x_vars[(opt_lp_x_vars['u'] == s_node_id) &
            #                       (opt_lp_x_vars['v'] == v_node_id + self.substrate_nodes)]['solution_value'].values,
            #     default=None
            # )

            selected_s_node_id = max(
                subset_S_per_v_node[v_node_id],
                key=lambda s_node_id:
                sum(opt_lp_f_vars[(opt_lp_f_vars['u'] == s_node_id) &
                                  (opt_lp_f_vars['v'] == v_node_id + self.substrate_nodes)]['solution_value'].values +
                    opt_lp_f_vars[(opt_lp_f_vars['u'] == v_node_id + self.substrate_nodes) &
                                  (opt_lp_f_vars['v'] == s_node_id)]['solution_value'].values) *
                    opt_lp_x_vars[(opt_lp_x_vars['u'] == s_node_id) &
                                  (opt_lp_x_vars['v'] == v_node_id + self.substrate_nodes)]['solution_value'].values[0],
                default=None
            )

            if selected_s_node_id is None:
                self.num_node_embedding_fails += 1
                msg = "VNR {0} REJECTED ({1}): 'no suitable SUBSTRATE NODE for nodal constraints: {2}' {3}".format(
                    vnr.id, self.num_node_embedding_fails, v_cpu_demand, vnr
                )
                self.logger.info("{0} {1}".format(utils.step_prefix(self.time_step), msg))
                self.revoke_from_augmented_substrate(copied_substrate, vnr, self.substrate_nodes)
                return None

            assert selected_s_node_id != -1
            embedding_s_nodes[v_node_id] = (selected_s_node_id, v_cpu_demand)
            if not self.allow_embedding_to_same_substrate_node:
                already_embedding_s_nodes.append(selected_s_node_id)

            assert copied_substrate.net.nodes[selected_s_node_id]['CPU'] >= v_cpu_demand
            copied_substrate.net.nodes[selected_s_node_id]['CPU'] -= v_cpu_demand

        self.revoke_from_augmented_substrate(copied_substrate, vnr, self.substrate_nodes)

        return embedding_s_nodes
Пример #13
0
    def find_substrate_nodes(self, copied_substrate, vnr):
        '''
        Execute Step 1
        :param copied_substrate: copied substrate network
        :param vnr: virtual network request
        :return: embedded substrate nodes
        '''
        subset_S_per_v_node = {}
        embedding_s_nodes = {}
        already_embedding_s_nodes = []

        # self.config.TYPE_OF_VIRTUAL_NODE_RANKING.TYPE_1
        sorted_v_nodes_with_node_ranking = utils.get_sorted_v_nodes_with_node_ranking(
            vnr=vnr,
            type_of_node_ranking=self.type_of_virtual_node_ranking,
            beta=self.beta)

        vnr_num_node = 0
        for v_node_id, v_node_data, _ in sorted_v_nodes_with_node_ranking:
            v_cpu_demand = v_node_data['CPU']
            v_node_location = v_node_data['LOCATION']

            if vnr_num_node == 0:
                # Find the subset S of substrate nodes that satisfy restrictions and
                # available CPU capacity (larger than that specified by the request.)
                subset_S_per_v_node[
                    v_node_id] = utils.find_subset_S_for_virtual_node(
                        copied_substrate, v_cpu_demand, v_node_location,
                        already_embedding_s_nodes)

                selected_s_node_id = max(
                    subset_S_per_v_node[v_node_id],
                    key=lambda s_node_id: self.calculate_node_ranking(
                        copied_substrate.net.nodes[s_node_id]['CPU'],
                        copied_substrate.net[s_node_id]),
                    default=None)

            elif vnr_num_node != 0 and selected_s_node_id is not None:
                radius = 1
                sub_ego_graph_length = 0
                while sub_ego_graph_length != len(copied_substrate.net.nodes):
                    # make the previous selected node's ego graph
                    sub_ego_graph = nx.ego_graph(copied_substrate.net,
                                                 selected_s_node_id,
                                                 radius=radius)
                    sub_ego_graph_length = len(sub_ego_graph.nodes)

                    subset_S_per_v_node[
                        v_node_id] = utils.find_subset_S_for_virtual_node(
                            sub_ego_graph, v_cpu_demand, v_node_location,
                            already_embedding_s_nodes)
                    if len(subset_S_per_v_node[v_node_id]) == 0:
                        if sub_ego_graph_length == len(
                                copied_substrate.net.nodes):
                            selected_s_node_id = None
                            break
                        else:
                            radius += 1
                            continue
                    else:
                        selected_s_node_id = max(
                            subset_S_per_v_node[v_node_id],
                            key=lambda s_node_id: self.calculate_node_ranking(
                                copied_substrate.net.nodes[s_node_id]['CPU'],
                                copied_substrate.net[s_node_id]),
                            default=None)

                    if selected_s_node_id is not None:
                        break
                    radius += 1

            vnr_num_node += 1

            if selected_s_node_id is None:
                self.num_node_embedding_fails += 1
                msg = "VNR {0} REJECTED ({1}): 'no suitable SUBSTRATE NODE for nodal constraints: {2}' {3}".format(
                    vnr.id, self.num_node_embedding_fails, v_cpu_demand, vnr)
                self.logger.info("{0} {1}".format(
                    utils.step_prefix(self.time_step), msg))
                return None

            assert selected_s_node_id != -1
            embedding_s_nodes[v_node_id] = (selected_s_node_id, v_cpu_demand)
            if not self.allow_embedding_to_same_substrate_node:
                already_embedding_s_nodes.append(selected_s_node_id)

            assert copied_substrate.net.nodes[selected_s_node_id][
                'CPU'] >= v_cpu_demand
            copied_substrate.net.nodes[selected_s_node_id][
                'CPU'] -= v_cpu_demand

        return embedding_s_nodes
Пример #14
0
    def find_substrate_path(self, copied_substrate, vnr, embedding_s_nodes):
        embedding_s_paths = {}

        # mapping the virtual nodes and substrate_net nodes
        for src_v_node, dst_v_node, edge_data in vnr.net.edges(data=True):
            v_link = (src_v_node, dst_v_node)
            src_s_node = embedding_s_nodes[src_v_node][0]
            dst_s_node = embedding_s_nodes[dst_v_node][0]
            v_bandwidth_demand = edge_data['bandwidth']

            if src_s_node == dst_s_node:
                embedding_s_paths[v_link] = ([], v_bandwidth_demand)
            else:
                subnet = nx.subgraph_view(
                    copied_substrate.net,
                    filter_edge=lambda node_1_id, node_2_id: \
                        True if copied_substrate.net.edges[(node_1_id, node_2_id)]['bandwidth'] >= v_bandwidth_demand else False
                )

                # Just for assertion
                # for u, v, a in subnet.edges(data=True):
                #     assert a["bandwidth"] >= v_bandwidth_demand

                if len(subnet.edges) == 0 or not nx.has_path(
                        subnet, source=src_s_node, target=dst_s_node):
                    self.num_link_embedding_fails += 1
                    msg = "VNR {0} REJECTED ({1}): 'no suitable LINK for bandwidth demand: {2} {3}".format(
                        vnr.id, self.num_link_embedding_fails,
                        v_bandwidth_demand, vnr)
                    self.logger.info("{0} {1}".format(
                        utils.step_prefix(self.time_step), msg))
                    return None

                MAX_K = 1

                shortest_s_path = utils.k_shortest_paths(subnet,
                                                         source=src_s_node,
                                                         target=dst_s_node,
                                                         k=MAX_K)[0]

                # Check the path length
                if len(shortest_s_path) > self.max_embedding_path_length:
                    self.num_link_embedding_fails += 1
                    msg = "VNR {0} REJECTED ({1}): 'no suitable LINK for bandwidth demand: {2} {3}".format(
                        vnr.id, self.num_link_embedding_fails,
                        v_bandwidth_demand, vnr)
                    self.logger.info("{0} {1}".format(
                        utils.step_prefix(self.time_step), msg))
                    return None

                # if hasattr(config, "MAX_EMBEDDING_PATH_LENGTH") and len(shortest_s_path) - 1 > config.MAX_EMBEDDING_PATH_LENGTH:
                #     self.num_link_embedding_fails += 1
                #     msg = "VNR {0} REJECTED ({1}): 'Suitable LINK for bandwidth demand, however the path length {2} is higher than {3}".format(
                #         vnr.id, self.num_link_embedding_fails, len(shortest_s_path) - 1, config.MAX_EMBEDDING_PATH_LENGTH
                #     )
                #     self.logger.info("{0} {1}".format(utils.step_prefix(self.time_step), msg))
                #     return None

                s_links_in_path = []
                for node_idx in range(len(shortest_s_path) - 1):
                    s_links_in_path.append((shortest_s_path[node_idx],
                                            shortest_s_path[node_idx + 1]))

                for s_link in s_links_in_path:
                    assert copied_substrate.net.edges[s_link][
                        'bandwidth'] >= v_bandwidth_demand
                    copied_substrate.net.edges[s_link][
                        'bandwidth'] -= v_bandwidth_demand

                embedding_s_paths[v_link] = (s_links_in_path,
                                             v_bandwidth_demand)

        return embedding_s_paths
Пример #15
0
    def find_substrate_path(self, copied_substrate, vnr, embedding_s_nodes):
        is_ok, results = utils.find_all_s_paths_2(copied_substrate,
                                                  embedding_s_nodes, vnr)

        if is_ok:
            all_s_paths = results
        else:
            (v_link, v_bandwidth_demand) = results
            self.num_link_embedding_fails += 1

            if v_bandwidth_demand:
                msg = "VNR {0} REJECTED ({1}): 'no suitable LINK for bandwidth demand: {2} {3}".format(
                    vnr.id, self.num_link_embedding_fails, v_bandwidth_demand,
                    vnr)
            else:
                msg = "VNR {0} REJECTED ({1}): 'not found for any substrate path for v_link: {2} {3}".format(
                    vnr.id, self.num_link_embedding_fails, v_link, vnr)

            self.logger.info("{0} {1}".format(
                utils.step_prefix(self.time_step), msg))
            return None

        # GENETIC ALGORITHM START: mapping the virtual nodes and substrate_net nodes
        print("[[VNR {0}] GA Started for {1} Virtual Links]".format(
            vnr.id, len(vnr.net.edges(data=True))))

        # LINK EMBEDDING VIA GENETIC ALGORITHM
        original_copied_substrate = copy.deepcopy(copied_substrate)

        early_stopping = GAEarlyStopping(patience=config.STOP_PATIENCE_COUNT,
                                         verbose=True,
                                         delta=0.0001,
                                         copied_substrate=copied_substrate)
        ga_operator = GAOperator(vnr, all_s_paths, copied_substrate,
                                 config.POPULATION_SIZE)
        ga_operator.initialize()
        generation_idx = 0
        while True:
            generation_idx += 1
            ga_operator.selection()
            ga_operator.crossover()
            ga_operator.mutation()
            ga_operator.sort_population_and_set_elite()

            solved, best_elite = early_stopping.evaluate(
                elite=ga_operator.elite,
                evaluation_value=ga_operator.elite.fitness)

            if solved:
                break

        assert original_copied_substrate == copied_substrate

        # s_path is selected from elite chromosome
        # early_stopping.print_best_elite()

        for v_link, (
                s_links_in_path,
                v_bandwidth_demand) in best_elite.embedding_s_paths.items():
            for s_link in s_links_in_path:
                if copied_substrate.net.edges[s_link][
                        'bandwidth'] < v_bandwidth_demand:
                    self.num_link_embedding_fails += 1

                    msg = "VNR {0} REJECTED ({1}): 'After GA (fitness: {2:.6f}) " \
                          "-> no suitable LINK for bandwidth demand: {3} {4}".format(
                        vnr.id, self.num_link_embedding_fails, best_elite.fitness, v_bandwidth_demand, vnr
                    )

                    self.logger.info("{0} {1}".format(
                        utils.step_prefix(self.time_step), msg))
                    return None

                copied_substrate.net.edges[s_link][
                    'bandwidth'] -= v_bandwidth_demand

        return best_elite.embedding_s_paths