def test_can_handle_request_whose_edge_demand_exceeds_all_substrate_capacities(self):
        self.request.edge[("m", "p")]["demand"] = 10**10
        scenario = datamodel.Scenario("test_scenario", self.substrate, [self.request],
                                      objective=datamodel.Objective.MAX_PROFIT)
        mc_ecg = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(scenario)
        mc_ecg.init_model_creator()
        sol = mc_ecg.compute_fractional_solution()
        assert mc_ecg.model.getAttr(GRB.Attr.ObjVal) == pytest.approx(1000.0)  # Can be solved by colocation

        # forbid colocation => should become infeasible
        self.request.set_allowed_nodes("m", {"u"})
        self.request.set_allowed_nodes("p", {"v"})
        mc_ecg = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(scenario)
        mc_ecg.init_model_creator()
        sol = mc_ecg.compute_fractional_solution()
        assert mc_ecg.model.getAttr(GRB.Attr.ObjVal) == pytest.approx(0.0)  # Cannot be solved by colocation
    def test_mc_ecg_does_not_ignore_unprofitable_requests_when_using_min_cost_objective(self):
        profit_req = copy.deepcopy(self.request)
        no_profit_req = copy.deepcopy(self.request)
        profit_req.name = "profit_req"
        no_profit_req.name = "no_profit_req"
        profit_req.profit = 1000.0
        no_profit_req.profit = 0.0
        scenario = datamodel.Scenario("test_scenario", self.substrate, [profit_req, no_profit_req],
                                      objective=datamodel.Objective.MIN_COST)
        mc_ecg = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(scenario)
        assert no_profit_req in mc_ecg.requests
        assert no_profit_req in mc_ecg.all_requests
        assert profit_req in mc_ecg.requests

        mc_ecg.init_model_creator()

        # Check that the unprofitable request is in the Gurobi Model:
        assert no_profit_req in mc_ecg.extended_graphs
        assert no_profit_req in mc_ecg.var_node_flow
        assert no_profit_req in mc_ecg.var_edge_flow
        assert no_profit_req in mc_ecg.var_request_load
        assert no_profit_req in mc_ecg.var_embedding_decision
        assert no_profit_req in mc_ecg.var_request_load

        fs = mc_ecg.compute_fractional_solution()
        # Check that the unprofitable request *is* in the fractional solution
        assert isinstance(fs, solutions.FractionalScenarioSolution)
        assert profit_req in fs.request_mapping
        assert no_profit_req in fs.request_mapping
        assert sum([fs.mapping_flows[m.name] for m in fs.request_mapping[profit_req]]) == 1
        assert sum([fs.mapping_flows[m.name] for m in fs.request_mapping[no_profit_req]]) == 1
        for i in profit_req.nodes:
            assert all(i in mapping.mapping_nodes for mapping in fs.request_mapping[profit_req])
        for ij in profit_req.edges:
            assert all(ij in mapping.mapping_edges for mapping in fs.request_mapping[profit_req])
 def test_can_handle_request_whose_node_demand_exceeds_all_substrate_capacities(self):
     self.request.node["p"]["demand"] = 10**10
     scenario = datamodel.Scenario("test_scenario", self.substrate, [self.request],
                                   objective=datamodel.Objective.MAX_PROFIT)
     mc_ecg = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(scenario)
     mc_ecg.init_model_creator()
     mc_ecg.model.optimize()
     assert mc_ecg.model.getAttr(GRB.Attr.ObjVal) == pytest.approx(0.0)
 def test_can_handle_request_whose_edge_demand_exceeds_some_substrate_capacities(self):
     self.request.edge[("m", "p")]["demand"] = 10.0  # m is allowed on u, v and p on v
     self.substrate.edge["w", "u"]["capacity"] = 1.0
     scenario = datamodel.Scenario("test_scenario", self.substrate, [self.request],
                                   objective=datamodel.Objective.MAX_PROFIT)
     mc_ecg = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(scenario)
     mc_ecg.init_model_creator()
     mc_ecg.model.optimize()
     assert mc_ecg.model.getAttr(GRB.Attr.ObjVal) == pytest.approx(1000.0)
 def test_can_handle_request_whose_node_demand_exceeds_some_substrate_capacities(self):
     self.request.node["q"]["demand"] = 10.0  # q is allowed on u, w
     self.substrate.node["w"]["capacity"]["universal"] = 1.0  # q no longer fits on w
     self.substrate.node["u"]["capacity"]["universal"] = 100.0  # q still fits on u
     scenario = datamodel.Scenario("test_scenario", self.substrate, [self.request],
                                   objective=datamodel.Objective.MAX_PROFIT)
     mc_ecg = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(scenario)
     mc_ecg.init_model_creator()
     mc_ecg.model.optimize()
     assert mc_ecg.model.getAttr(GRB.Attr.ObjVal) == pytest.approx(1000.0)
 def test_example_get_load_based_on_integral_solution(self):
     scenario = datamodel.Scenario("test_scenario", self.substrate, [self.request],
                                   objective=datamodel.Objective.MIN_COST)
     mc_mip = mip.ClassicMCFModel(scenario)
     mc_mip.init_model_creator()
     sol = mc_mip.compute_integral_solution().solution
     mc_ecg = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(sol.scenario)
     mc_ecg.init_model_creator()
     mc_ecg.fix_mapping_variables_according_to_integral_solution(sol)
     mc_ecg.model.optimize()
     assert mc_mip.model.getAttr(GRB.Attr.ObjVal) == pytest.approx(mc_ecg.model.getAttr(GRB.Attr.ObjVal))
 def test_can_get_fractional_solution(self):
     scenario = datamodel.Scenario("test_scenario", self.substrate, [self.request],
                                   objective=datamodel.Objective.MIN_COST)
     mc_ecg = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(scenario)
     mc_ecg.init_model_creator()
     fs = mc_ecg.compute_fractional_solution()
     assert isinstance(fs, solutions.FractionalScenarioSolution)
     for req in scenario.requests:
         assert req in fs.request_mapping
         # ensure that all nodes & edges are in each mapping
         for i in req.nodes:
             assert all(i in mapping.mapping_nodes for mapping in fs.request_mapping[req])
         for ij in req.edges:
             assert all(ij in mapping.mapping_edges for mapping in fs.request_mapping[req])
    def test_model_fixing_simple_scenario(self):
        sub = datamodel.Substrate("fixing_sub")
        sub.add_node("u", {"t1"}, {"t1": 10}, {"t1": 100})
        sub.add_node("v", {"t1"}, {"t1": 10}, {"t1": 100})
        sub.add_node("w", {"t1"}, {"t1": 10}, {"t1": 100})
        sub.add_node("x", {"t1"}, {"t1": 10}, {"t1": 100})
        sub.add_edge("u", "v")
        sub.add_edge("v", "w")
        sub.add_edge("w", "x")
        sub.add_edge("x", "u")

        req = datamodel.Request("fixing_req")
        req.profit = 1000
        req.add_node("i", 5, "t1", {"u", "v", "w", "x"})
        req.add_node("j", 5, "t1", {"u", "v", "w", "x"})
        req.add_edge("i", "j", 0.5)

        mapping = solutions.Mapping("fixing_mapping", req, sub, True)
        mapping.map_node("i", "u")
        mapping.map_node("j", "x")
        mapping.map_edge(("i", "j"), [("u", "v"), ("v", "w"), ("w", "x")])

        scenario = datamodel.Scenario("fixing_scen", sub, [req],
                                      datamodel.Objective.MAX_PROFIT)
        sol = solutions.IntegralScenarioSolution("fixing_sol", scenario)
        sol.add_mapping(req, mapping)

        mc_ecg = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(
            scenario)
        mc_ecg.init_model_creator()
        mc_ecg.fix_mapping_variables_according_to_integral_solution(sol)
        ecg_sol = mc_ecg.compute_integral_solution()

        new_mapping = ecg_sol.solution.request_mapping[req]
        assert new_mapping.mapping_nodes == mapping.mapping_nodes
        assert new_mapping.mapping_edges == mapping.mapping_edges
 def test_variables(self):
     scenario = datamodel.Scenario("test_scenario", self.substrate,
                                   [self.request])
     mc = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(
         scenario)
     mc.init_model_creator()
    def test_ecg_and_mcf_should_obtain_same_solution_when_variables_are_fixed(
            self):
        real_scenario = self.make_real_scenario()
        real_scenario.objective = datamodel.Objective.MAX_PROFIT
        time_limit = 200

        mc_preprocess = mip.ClassicMCFModel(real_scenario)
        mc_preprocess.init_model_creator()
        mc_preprocess.set_gurobi_parameter(modelcreator.Param_TimeLimit,
                                           time_limit)
        sol_preprocess = mc_preprocess.compute_integral_solution().solution

        usable_requests = [
            req for req in real_scenario.requests
            if sol_preprocess.request_mapping[req].is_embedded
        ]
        assert len(usable_requests) != 0

        real_scenario.requests = usable_requests
        real_scenario.objective = datamodel.Objective.MIN_COST

        # First, compute solution using MCF model and fix variables of Decomposition
        mc_mcf = mip.ClassicMCFModel(real_scenario)
        mc_mcf.init_model_creator()
        mc_mcf.set_gurobi_parameter(modelcreator.Param_TimeLimit, time_limit)
        sol_mcf = mc_mcf.compute_integral_solution().get_solution()
        sol_mcf.validate_solution_fulfills_capacity()

        assert any(m.is_embedded
                   for m in list(sol_mcf.request_mapping.values()))

        mc_ecg_fixed_mapping = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(
            real_scenario)
        mc_ecg_fixed_mapping.init_model_creator()
        mc_ecg_fixed_mapping.set_gurobi_parameter(modelcreator.Param_TimeLimit,
                                                  time_limit)
        mc_ecg_fixed_mapping.fix_mapping_variables_according_to_integral_solution(
            sol_mcf)
        sol_ecg_fixed_mapping = mc_ecg_fixed_mapping.compute_integral_solution(
        )

        assert mc_mcf.model.objVal == pytest.approx(
            mc_ecg_fixed_mapping.model.objVal)
        for req in usable_requests:
            mcf_mapping = sol_mcf.request_mapping[req]
            ecg_mapping = sol_ecg_fixed_mapping.get_solution(
            ).request_mapping[req]
            print(mcf_mapping.mapping_nodes)
            print(ecg_mapping.mapping_nodes)
            assert mcf_mapping.mapping_nodes == ecg_mapping.mapping_nodes
            assert mcf_mapping.mapping_edges == ecg_mapping.mapping_edges

        # compute solution using Decomposition and fix variables of MCF model
        mc_ecg_fixed_mapping = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(
            real_scenario)
        mc_ecg_fixed_mapping.init_model_creator()
        mc_ecg_fixed_mapping.set_gurobi_parameter(modelcreator.Param_TimeLimit,
                                                  time_limit)
        sol_ecg = mc_ecg_fixed_mapping.compute_integral_solution(
        ).get_solution()

        assert any(m.is_embedded
                   for m in list(sol_ecg.request_mapping.values()))

        mc_mcf_fixed_mapping = mip.ClassicMCFModel(real_scenario)
        mc_mcf_fixed_mapping.init_model_creator()
        mc_mcf_fixed_mapping.set_gurobi_parameter(modelcreator.Param_TimeLimit,
                                                  time_limit)
        mc_mcf_fixed_mapping.fix_mapping_variables_according_to_integral_solution(
            sol_ecg)
        sol_mcf_fixed_mapping = mc_mcf_fixed_mapping.compute_integral_solution(
        ).solution
        sol_mcf_fixed_mapping.validate_solution_fulfills_capacity()

        assert mc_mcf_fixed_mapping.model.objVal == pytest.approx(
            mc_ecg_fixed_mapping.model.objVal)
        for req in usable_requests:
            mcf_mapping = sol_mcf_fixed_mapping.request_mapping[req]
            ecg_mapping = sol_ecg.request_mapping[req]
            assert mcf_mapping.mapping_nodes == ecg_mapping.mapping_nodes
            assert mcf_mapping.mapping_edges == ecg_mapping.mapping_edges