Ejemplo n.º 1
0
    def recover_fractional_solution_from_variables(self):
        solution_name = modelcreator.construct_name(
            "solution_", req_name="", sub_name=self.substrate.name)
        self.solution = solutions.FractionalScenarioSolution(
            solution_name, self.scenario)
        for req in self.requests:
            # mapping_name = modelcreator.construct_name("fractual_mapping_", req_name=req.name,
            #                              sub_name=self.substrate.name)
            is_embedded = self.var_embedding_decision[req].x > 0.5
            # mapping = mp_pkg.Mapping(mapping_name, req, self.substrate, is_embedded=is_embedded)

            if is_embedded:
                maps = self.obtain_fractional_mappings_of_request(req)
                if not maps:
                    mapping_name = modelcreator.construct_name(
                        "empty_mapping_",
                        req_name=req.name,
                        sub_name=self.substrate.name)
                    self.solution.add_mapping(
                        req,
                        solutions.Mapping(mapping_name, req, self.substrate,
                                          False), {}, {})
                for m, flow, load in maps:
                    self.solution.add_mapping(req, m, flow, load)
                    # TODO: even if the request is not embedded, a mapping object should be created, indicating that the request was not embedded
        return self.solution
Ejemplo n.º 2
0
def test_construct_name():
    assert construct_name("foo") == "foo"
    assert construct_name(
        name="node_mapping",
        req_name="req1",
        snode="u",
        vnode="i",
    ) == "node_mapping_req[req1]_vnode[i]_snode[u]"
    assert construct_name(
        "compute_edge_load",
        req_name="req1",
        sedge=("u", "v"),
    ) == "compute_edge_load_req[req1]_sedge[('u','v')]"
    assert construct_name(
        name="1",
        req_name=2,
        type=3,
        vnode=4,
        snode=5,
        vedge=6,
        sedge=7,
        other=8,
        sub_name=9,
        sol_name=10,
    ) == "1_req[2]_type[3]_vnode[4]_snode[5]_vedge[6]_sedge[7]_other[8]_substrate[9]_solution[10]"
Ejemplo n.º 3
0
    def recover_integral_solution_from_variables(self):
        solution_name = modelcreator.construct_name(
            "solution_", req_name="", sub_name=self.substrate.name)
        self.solution = solutions.IntegralScenarioSolution(
            solution_name, self.scenario)

        for req in self.requests:

            # create mapping for specific req and substrate
            mapping_name = modelcreator.construct_name(
                "mapping_", req_name=req.name, sub_name=self.substrate.name)

            is_embedded = self.var_embedding_decision[req].x > 0.5

            mapping = solutions.Mapping(mapping_name,
                                        req,
                                        self.substrate,
                                        is_embedded=is_embedded)

            if is_embedded:
                self.obtain_integral_mapping_of_request(req, mapping)

            self.solution.add_mapping(req, mapping)

        return self.solution
Ejemplo n.º 4
0
 def _get_empty_mapping_of_correct_type(self):
     if self.edge_embedding_model == ViNEEdgeEmbeddingModel.UNSPLITTABLE:
         name = mc.construct_name(
             "shortest_path_mapping_", req_name=self._current_request.name, sub_name=self.original_substrate.name
         )
         return solutions.Mapping(
             name, self._current_request, self.original_substrate, is_embedded=True,
         )
     elif self.edge_embedding_model == ViNEEdgeEmbeddingModel.SPLITTABLE:
         name = mc.construct_name(
             "splittable_mapping_", req_name=self._current_request.name, sub_name=self.original_substrate.name
         )
         return SplittableMapping(
             name, self._current_request, self.original_substrate, is_embedded=True,
         )
     else:
         raise ValueError("Invalid edge mapping method: {}".format(self.edge_embedding_model))
Ejemplo n.º 5
0
    def _flow_induction_constraints(self):
        for req in self.requests:
            ext_graph = self.extended_graph[req]

            ssource = ext_graph.super_source

            expr = LinExpr([(-1.0, self.var_embedding_decision[req])] +
                           [(1.0, self.var_flow[req][sedge_ext])
                            for sedge_ext in ext_graph.out_edges[ssource]])

            constr_name = modelcreator.construct_name("flow_induction",
                                                      req_name=req.name)
            self.model.addConstr(expr, GRB.EQUAL, 0.0, name=constr_name)
Ejemplo n.º 6
0
    def _load_computation_nodes_constraints(self):
        for req in self.requests:
            for (ntype, snode) in self.substrate.substrate_node_resources:
                expr = LinExpr(
                    [(req.get_node_demand(i), self.var_flow[req][sedge_ext])
                     for (sedge_ext, i) in self.ext_graph_edges_node[req][
                         (ntype, snode)]] +
                    [(-1.0, self.var_request_load[req][(ntype, snode)])])

                constr_name = modelcreator.construct_name("compute_node_load",
                                                          req_name=req.name,
                                                          snode=snode,
                                                          type=ntype)
                self.model.addConstr(expr, GRB.EQUAL, 0.0, name=constr_name)
Ejemplo n.º 7
0
    def create_variables_other_than_embedding_decision_and_request_load(self):
        # flow variables
        for req in self.requests:
            self.var_flow[req] = {}

            for sedge_ext in self.extended_graph[req].edges:
                variable_id = modelcreator.construct_name("flow",
                                                          req_name=req.name,
                                                          other=sedge_ext)
                self.var_flow[req][sedge_ext] = self.model.addVar(
                    lb=0.0,
                    ub=1.0,
                    obj=0.0,
                    vtype=GRB.BINARY,
                    name=variable_id)
Ejemplo n.º 8
0
    def obtain_fractional_mappings_of_request(self, req, eps=0.00001):
        maps = []
        total_flow = self.var_flow[req]
        ext_graph = self.extended_graph[req]
        # dictionary: edge(from extended graph) -> remaining flow
        remaining_flow_dict = {
            eedge: total_flow[eedge].X
            for eedge in ext_graph.edges
        }
        sum_outgoing_flow_super_source = self.var_embedding_decision[req].x
        number_maps = 0
        while sum_outgoing_flow_super_source > eps:
            predecessor_dict = ModelCreatorDecomp._search_path_through_extended_graph(
                ext_graph, remaining_flow_dict)

            # reconstruct path
            eedge_path = []
            current_enode = ext_graph.super_sink
            min_flow_on_path = 1.0
            while current_enode is not ext_graph.super_source:
                previous_hop = predecessor_dict[current_enode]
                eedge = (previous_hop, current_enode)
                min_flow_on_path = min(min_flow_on_path,
                                       remaining_flow_dict[eedge])
                eedge_path.append((previous_hop, current_enode))
                current_enode = previous_hop
            # reverse edges such that path leads from super source to super sink
            eedge_path.reverse()
            for eedge in eedge_path:
                remaining_flow_dict[eedge] -= min_flow_on_path
            sum_outgoing_flow_super_source -= min_flow_on_path
            # lookup minimal used_flow on any of the edges TODO

            mapping_name = modelcreator.construct_name(
                "mapping_" + str(number_maps),
                req_name=req.name,
                sub_name=self.substrate.name)
            number_maps += 1
            mapping, load = self._get_fractional_mapping_and_load_from_path(
                req, mapping_name, ext_graph, eedge_path)
            # RECONSTRUCT MAPPING FROM PATH
            maps.append((mapping, min_flow_on_path, load))
        return maps
Ejemplo n.º 9
0
    def _flow_preservation_constraints(self):
        for req in self.requests:
            ext_graph = self.extended_graph[req]

            for ext_node in ext_graph.nodes:

                if ext_node == ext_graph.super_source or ext_node == ext_graph.super_sink:
                    continue

                expr = LinExpr(
                    [(+1.0, self.var_flow[req][sedge_ext])
                     for sedge_ext in ext_graph.out_edges[ext_node]] +
                    [(-1.0, self.var_flow[req][sedge_ext])
                     for sedge_ext in ext_graph.in_edges[ext_node]])

                constr_name = modelcreator.construct_name("flow_preservation",
                                                          req_name=req.name,
                                                          other=ext_node)
                self.model.addConstr(expr, GRB.EQUAL, 0.0, name=constr_name)
Ejemplo n.º 10
0
    def compute_integral_solution(self):
        vine_instance = ViNESingleScenario(
            substrate=self.scenario.substrate,
            vine_settings=self.vine_settings,
            gurobi_settings=self.gurobi_settings,
            optimization_callback=self.optimization_callback,
            lp_output_file=self.lp_output_file,
            potential_iis_filename=self.potential_iis_filename,
            logger=self.logger
        )


        solution_name = mc.construct_name("solution_", sub_name=self.scenario.name)
        solution = solutions.IntegralScenarioSolution(solution_name, self.scenario)

        overall_runtime_start = time.time()
        runtime_per_request = {}
        mapping_status_per_request = {}
        for req in sorted(self.scenario.requests, key=lambda r: r.profit, reverse=True):
            t_start = time.time()
            mapping, status = vine_instance.vine_procedure_single_request(req)

            runtime_per_request[req] = time.time() - t_start
            mapping_status_per_request[req] = status

            solution.add_mapping(req, mapping)

        # assert solution.validate_solution()                       test is limited but worked, no need to keep it in the evaluation
        # assert solution.validate_solution_fulfills_capacity()     test is limited but worked, no need to keep it in the evaluation

        overall_runtime = time.time() - overall_runtime_start
        result = OfflineViNEResult(
            solution=solution,
            vine_settings=self.vine_settings,
            runtime=overall_runtime,
            runtime_per_request=runtime_per_request,
            mapping_status_per_request=mapping_status_per_request,
        )
        return result