def setup(self): self.substrate = datamodel.Substrate("paper_example_substrate") self.substrate.add_node("u", ["universal"], {"universal": 1000}, {"universal": 0.0}) self.substrate.add_node("v", ["universal"], {"universal": 1000}, {"universal": 0.0}) self.substrate.add_node("w", ["universal"], {"universal": 1000}, {"universal": 0.0}) self.substrate.add_edge("u", "v", capacity=1000, bidirected=False) self.substrate.add_edge("v", "w", capacity=1000, bidirected=False) self.substrate.add_edge("w", "u", capacity=1000, bidirected=False) self.request = datamodel.Request("paper_example_request") self.request.add_node("i", 0.0, "universal", ["w"]) self.request.add_node("j", 0.0, "universal", ["v", "w"]) self.request.add_node("k", 0.0, "universal", ["u"]) self.request.add_node("l", 0.0, "universal", ["u", "w"]) self.request.add_node("m", 0.0, "universal", ["u", "v"]) self.request.add_node("n", 0.0, "universal", ["u", "v"]) self.request.add_node("p", 0.0, "universal", ["v"]) self.request.add_node("q", 0.0, "universal", ["u", "w"]) self.request.add_edge("i", "j", 0.0) self.request.add_edge("j", "k", 0.0) self.request.add_edge("k", "l", 0.0) self.request.add_edge("l", "m", 0.0) self.request.add_edge("m", "j", 0.0) self.request.add_edge("m", "p", 0.0) self.request.add_edge("p", "n", 0.0) self.request.add_edge("p", "q", 0.0) self.request.graph["root"] = "j" self.single_edge_sub = datamodel.Substrate("simple_substrate") self.single_edge_sub.add_node("u", ["universal"], {"universal": 1000}, {"universal": 0.0}) self.single_edge_sub.add_node("v", ["universal"], {"universal": 1000}, {"universal": 0.0}) self.single_edge_sub.add_edge("u", "v", capacity=1000, bidirected=False) self.simple_cycle_req = datamodel.Request("simple_cycle_request") self.simple_cycle_req.add_node("i", 0.0, "universal", ["u"]) self.simple_cycle_req.add_node("j", 0.0, "universal", ["v"]) self.simple_cycle_req.add_node("k", 0.0, "universal", ["w"]) self.simple_cycle_req.add_edge("i", "j", 0.0) self.simple_cycle_req.add_edge("j", "k", 0.0) self.simple_cycle_req.add_edge("k", "i", 0.0) self.simple_cycle_req.graph["root"] = "i" self.single_edge_req = datamodel.Request("simple_path_request") self.single_edge_req.add_node("i", 0.0, "universal", ["u", "w"]) self.single_edge_req.add_node("j", 0.0, "universal", ["w", "v"]) self.single_edge_req.add_edge("i", "j", 0.0) self.single_edge_req.graph["root"] = "i"
def construct_sptp_substrate(): # to check shortest path tree property sub = datamodel.Substrate("test_sub_sptp") sub.add_node("u", types=["t1"], capacity={"t1": 100}, cost={"t1": 1.0}) sub.add_node("v", types=["t1"], capacity={"t1": 100}, cost={"t1": 1.0}) sub.add_node("t", types=["t1"], capacity={"t1": 100}, cost={"t1": 1.0}) sub.add_node("s", types=["t1"], capacity={"t1": 100}, cost={"t1": 1.0}) sub.add_edge("u", "v", capacity=100.0, cost=1.0, bidirected=False) sub.add_edge("v", "t", capacity=100.0, cost=1.0, bidirected=False) sub.add_edge("s", "u", capacity=100.0, cost=1.0, bidirected=False) sub.add_edge("s", "v", capacity=100.0, cost=1.0, bidirected=False) edge_costs = { ("u", "v"): 3, ("s", "v"): 1, ("v", "t"): 5, ("s", "u"): 1, } edge_latencies = { ("u", "v"): 2, ("s", "v"): 9, ("v", "t"): 2, ("s", "u"): 4, } return sub, edge_costs, edge_latencies
def create_large_substrate(num_nodes, edge_res_factor): import string names = [] i = 1 while num_nodes > 26: names.extend([i * c for c in string.ascii_lowercase]) num_nodes -= 26 i += 1 names.extend([i * c for c in string.ascii_lowercase[:num_nodes]]) sub = datamodel.Substrate("test_sub_" + str(num_nodes) + "_nodes") for letter in names: sub.add_node(letter, types=["t1"], capacity={"t1": 100}, cost={"t1": 1.0}) for i, start in enumerate(names): for end in names[i + 1:]: if random.random() <= edge_res_factor: sub.add_edge(start, end, capacity=100.0, cost=1.0, bidirected=False) return sub
def _make_reversed_substrate(self): """ Generate a copy of the substrate with all edges reversed. All default substrate node & edge properties are preserved :return: """ reversed_substrate = datamodel.Substrate("{}_reversed".format( self._original_substrate.name)) for node in self._original_substrate.nodes: reversed_substrate.add_node( node, self._original_substrate.node[node]["supported_types"], self._original_substrate.node[node]["capacity"], self._original_substrate.node[node]["cost"]) reversed_substrate.node[node] = self._original_substrate.node[node] for tail, head in self._original_substrate.edges: original_edge_properties = self._original_substrate.edge[(tail, head)] reversed_substrate.add_edge( head, tail, capacity=original_edge_properties["capacity"], cost=original_edge_properties["cost"], bidirected=False) # copy any additional entries of the substrate's edge dict: for key, value in self._original_substrate.edge[( tail, head)].iteritems(): if key not in reversed_substrate.edge[(head, tail)]: reversed_substrate.edge[(head, tail)][key] = value return reversed_substrate
def create_test_substrate(substrate_id, node_capacities=None, node_costs=None, edge_capacities=None, edge_costs=None, bidirected_edges=False): """ Node types are implicitly defined by the dictionary keys of node_capacities. (default ["t"]) """ if node_capacities is None: node_capacities = {} if node_costs is None: node_costs = {} if edge_capacities is None: edge_capacities = {} if edge_costs is None: edge_costs = {} sub_nodes = SUBSTRATE_TOPOLOGIES[substrate_id]["nodes"] sub_edges = SUBSTRATE_TOPOLOGIES[substrate_id]["edges"] sub = datamodel.Substrate("{}_sub".format(substrate_id.replace(" ", "_"))) for u in sub_nodes: u_types = node_capacities.get(u).keys() if u in node_capacities else ["t"] u_capacities = node_capacities.get(u) if u in node_capacities else dict(t=1.0) u_costs = node_costs.get(u) if u in node_costs else {t: 1.0 for t in u_capacities} sub.add_node(u, types=u_types, capacity=u_capacities, cost=u_costs) for uv in sub_edges: uv_capacity = edge_capacities.get(uv, 1.0) uv_cost = edge_costs.get(uv, 1.0) u, v = uv sub.add_edge(u, v, capacity=uv_capacity, cost=uv_cost, bidirected=bidirected_edges) return sub
def test_decomposition_can_handle_splitting_flows(self): req = datamodel.Request("test_req") req.add_node("root", 1.0, "t1", allowed_nodes=["w"]) req.add_node("n2", 1.0, "t1", allowed_nodes=["v", "w"]) req.add_node("n3", 1.0, "t1", allowed_nodes=["u"]) req.add_edge("root", "n2", 1.0) req.add_edge("root", "n3", 1.0) req.add_edge("n2", "n3", 1.0) req.graph["root"] = "root" sub = datamodel.Substrate("test_sub") sub.add_node("u", ["t1"], {"t1": 100}, {"t1": 100}) sub.add_node("v", ["t1"], {"t1": 100}, {"t1": 100}) sub.add_node("w", ["t1"], {"t1": 100}, {"t1": 100}) sub.add_edge("u", "v", 1000.0, bidirected=True) sub.add_edge("v", "w", 1000.0, bidirected=True) sub.add_edge("w", "u", 1000.0, bidirected=True) # this is a simple request with a splitting flow that caused 200+ mappings due to a bug flow_values = { 'node': { 'root': { 'w': 0.5652934510902061 }, 'n3': { 'u': 0.565293451090206 } }, 'embedding': 0.5652934510902061, 'edge': { ('v_[n2n3]_[u]', 'u_[n2n3]_[u]'): 0.5625924430120608, ('w_[n2n3]_[u]', 'v_[n2n3]_[u]'): 0.16087557584604475, ('u_[rootn3]_[u]', 'u_[n3]_-'): 0.5652934510902061, ('v_[rootn2]_[u]', 'v_[n2n3]_[u]'): 0.40171686716601607, ('w_[root]_+', 'w_[rootn2]_[u]'): 0.5652934510902061, ('w_[rootn2]_[u]', 'v_[rootn2]_[u]'): 0.40171686716601607, ('w_[rootn3]_[u]', 'u_[rootn3]_[u]'): 0.5652934510902061, ('w_[root]_+', 'w_[rootn3]_[u]'): 0.5652934510902061, ('w_[n2n3]_[u]', 'u_[n2n3]_[u]'): 0.00270100807814525, ('w_[rootn2]_[u]', 'w_[n2n3]_[u]'): 0.16357658392419, ('u_[n2n3]_[u]', 'u_[n3]_-'): 0.565293451090206 } } decomposition = modelcreator_ecg_decomposition.Decomposition( req, sub, flow_values, 0.0001, 0.0001, 1e-10) mappings = decomposition.compute_mappings() assert len(mappings) == 3 expected_flow_values = { 0.40171686716601607, 0.16087557584604475, 0.00270100807814525 } for m, flow, load in mappings: best_matching_value = min( (expected for expected in expected_flow_values), key=lambda expected: abs(expected - flow)) expected_flow_values.remove(best_matching_value) assert flow == pytest.approx(best_matching_value, rel=0.001)
def get_test_substrate(types=None): sub = datamodel.Substrate("foo") if types is None: types = ["test_type"] sub.add_node( "u", types=types, capacity={t: 2.0 for t in types}, cost={t: 5 * random.random() for t in types}, ) sub.add_node( "v", types=types, capacity={t: 2.0 for t in types}, cost={t: 5 * random.random() for t in types}, ) sub.add_node( "w", types=types, capacity={t: 2.0 for t in types}, cost={t: 5 * random.random() for t in types}, ) sub.add_edge("u", "v", capacity=2.0, cost=random.random()) sub.add_edge("v", "w", capacity=2.0, cost=random.random()) sub.add_edge("w", "u", capacity=2.0, cost=random.random()) return sub
def setup(self): scenariogeneration.random.seed(5) self.substrate = datamodel.Substrate("paper_example_substrate") self.substrate.add_node("u", ["universal"], {"universal": 10}, {"universal": 0.8}) self.substrate.add_node("v", ["universal"], {"universal": 10}, {"universal": 1.2}) self.substrate.add_node("w", ["universal"], {"universal": 10}, {"universal": 1.0}) self.substrate.add_edge("u", "v", capacity=100, bidirected=False) self.substrate.add_edge("v", "w", capacity=100, bidirected=False) self.substrate.add_edge("w", "u", capacity=100, bidirected=False) self.request = datamodel.Request("test") self.request.add_node("i", 0.33, "universal", ["w"]) self.request.add_node("j", 0.33, "universal", ["v", "w"]) self.request.add_node("k", 0.33, "universal", ["u"]) self.request.add_node("l", 0.33, "universal", ["u", "w"]) self.request.add_node("m", 0.33, "universal", ["u", "v"]) self.request.add_node("n", 0.33, "universal", ["u", "v"]) self.request.add_node("p", 0.33, "universal", ["v"]) self.request.add_node("q", 0.33, "universal", ["u", "w"]) self.request.add_edge("i", "j", 0.25) self.request.add_edge("j", "k", 0.25) self.request.add_edge("k", "l", 0.25) self.request.add_edge("l", "m", 0.25) self.request.add_edge("m", "j", 0.25) self.request.add_edge("m", "p", 0.25) self.request.add_edge("p", "n", 0.25) self.request.add_edge("p", "q", 0.25) self.request.profit = 1000.0 self.request.graph["root"] = "j" scenariogeneration.random.seed(0) self.sg = scenariogeneration.ScenarioGenerator("test")
def get_test_substrate(number_of_nodes, node_types=None, capacity=10.0): """ Generate a complete graph as a substrate. :param number_of_nodes: :param name: :param demand: :return: """ if node_types is None: node_types = [scenariogeneration.UNIVERSAL_NODE_TYPE] test_substrate = datamodel.Substrate("test_substrate") capacity = {nt: capacity for nt in node_types} cost = {nt: 1.0 for nt in node_types} for i in range(1, number_of_nodes + 1): test_substrate.add_node("test_substrate_node_{}".format(i), node_types, capacity, cost) for i in range(1, number_of_nodes + 1): for j in range(i + 1, number_of_nodes + 1): test_substrate.add_edge("test_substrate_node_{}".format(i), "test_substrate_node_{}".format(j), capacity['universal'], bidirected=True) test_substrate.initialize_shortest_paths_costs() return test_substrate
def test_exclude_edge_mappings_with_insufficient_resources(self): sub = datamodel.Substrate("paper_example_substrate") sub.add_node("u", ["universal"], {"universal": 100}, {"universal": 0.0}) sub.add_node("v", ["universal"], {"universal": 100}, {"universal": 0.0}) sub.add_node("w", ["universal"], {"universal": 100}, {"universal": 0.0}) sub.add_edge("u", "v", capacity=1, bidirected=False) sub.add_edge("v", "w", capacity=1000, bidirected=False) sub.add_edge("w", "u", capacity=1000, bidirected=False) req = datamodel.Request("test") req.add_node("n1", 0.0, "universal", ["u"]) req.add_node("n2", 0.0, "universal", ["v"]) req.add_node("n3", 0.0, "universal", ["w"]) req.add_edge("n1", "n2", 10.0) req.add_edge("n2", "n3", 0.0) req.graph["root"] = "n1" insufficient_ext_edge = (ExtendedCactusGraph._super_node_name( ("n1", "n2"), "u", "layer"), ExtendedCactusGraph._super_node_name( ("n1", "n2"), "v", "layer")) ok_ext_edge = (ExtendedCactusGraph._super_node_name(("n2", "n3"), "u", "layer"), ExtendedCactusGraph._super_node_name(("n2", "n3"), "v", "layer")) eg = ExtendedCactusGraph(req, sub) assert insufficient_ext_edge not in eg.edges, "Extended graph contained edge corresponding to infeasible edge mapping!" assert ok_ext_edge in eg.edges, "Extended graph did not contain edge corresponding to feasible edge mapping!"
def create_test_substrate_topology_zoo(): sub = datamodel.Substrate("test_sub") sub.add_node("u", types=["t1"], capacity={"t1": 100}, cost={"t1": 1.0}) sub.add_node("v", types=["t1"], capacity={"t1": 100}, cost={"t1": 1.0}) sub.add_node("w", types=["t1"], capacity={"t1": 100}, cost={"t1": 1.0}) sub.add_edge("u", "v", capacity=100.0, cost=1.0, bidirected=False, latency=1.0) sub.add_edge("v", "w", capacity=100.0, cost=1.0, bidirected=False, latency=1.0) sub.add_edge("w", "u", capacity=100.0, cost=1.0, bidirected=False, latency=2.0) return sub
def substrate(): substr = datamodel.Substrate("substrate") substr.add_node(u, ["t1"], capacity={"t1": 10000}, cost={"t1": 1}) substr.add_node(v, ["t1"], capacity={"t1": 10000}, cost={"t1": 1}) substr.add_node(w, ["t1"], capacity={"t1": 10000}, cost={"t1": 1}) substr.add_edge(u, v, capacity=10000, cost=1, bidirected=True) substr.add_edge(v, w, capacity=10000, cost=1, bidirected=True) substr.add_edge(u, w, capacity=10000, cost=1, bidirected=True) return substr
def setup(self): self.substrate = datamodel.Substrate("sub1") self.request = datamodel.Request("req1") self.scenario = datamodel.Scenario("Sen1", self.substrate, [self.request]) self.mapping = solutions.Mapping("map1", self.request, self.substrate, True) self.scenariosolution = solutions.IntegralScenarioSolution( "Solution1", self.scenario)
def setup(self): self.substrate = datamodel.Substrate("paper_example_substrate") self.substrate.add_node("u", ["t1"], {"t1": 1}, {"t1": 0.0}) self.substrate.add_node("v", ["t1"], {"t1": 2}, {"t1": 0.0}) self.substrate.add_node("w", ["t1", "t2"], {"t1": 3, "t2": 5}, {"t1": 0.0, "t2": 0.0}) self.substrate.add_node("x", ["t2"], {"t2": 1}, {"t2": 0.0}) self.substrate.add_edge("u", "v", capacity=1000, bidirected=True) self.substrate.add_edge("u", "w", capacity=1, bidirected=False) self.substrate.add_edge("u", "x", capacity=100, bidirected=False) self.substrate_x = datamodel.SubstrateX(self.substrate)
def build_triangle(): sub = datamodel.Substrate("test_sub_triangle") sub.add_node("u", types=["t1"], capacity={"t1": 100}, cost={"t1": 1.0}) sub.add_node("v", types=["t1"], capacity={"t1": 100}, cost={"t1": 1.0}) sub.add_node("w", types=["t1"], capacity={"t1": 100}, cost={"t1": 1.0}) sub.add_node("x", types=["t1"], capacity={"t1": 100}, cost={"t1": 1.0}) sub.add_edge("u", "v", capacity=100.0, cost=1.0, bidirected=False) sub.add_edge("v", "w", capacity=100.0, cost=1.0, bidirected=False) sub.add_edge("u", "w", capacity=100.0, cost=1.0, bidirected=False) sub.add_edge("w", "x", capacity=100.0, cost=1.0, bidirected=False) return sub
def test_exclude_node_mappings_with_insufficient_resources(self): sub = datamodel.Substrate("paper_example_substrate") sub.add_node("u", ["t1", "t2"], { "t1": 100, "t2": 100 }, { "t1": 0.0, "t2": 0.0 }) sub.add_node("v", ["t1", "t2"], { "t1": 100, "t2": 0.0 }, { "t1": 0.0, "t2": 0.0 }) sub.add_node("w", ["t1", "t2"], { "t1": 100, "t2": 100 }, { "t1": 0.0, "t2": 0.0 }) sub.add_edge("u", "v", capacity=1000, bidirected=False) sub.add_edge("v", "w", capacity=1000, bidirected=False) sub.add_edge("w", "u", capacity=1000, bidirected=False) req = datamodel.Request("test") req.add_node("n1", 10.0, "t1", allowed_nodes=["u"]) req.add_node("n2", 10.0, "t2", allowed_nodes=["v", "w"]) req.add_node("n3", 10.0, "t1", allowed_nodes=["w"]) req.add_edge("n1", "n2", 10.0) req.add_edge("n2", "n3", 0.0) req.graph["root"] = "n1" should_not_exist = (ExtendedCactusGraph._super_node_name( ("n1", "n2"), "v", "layer"), ExtendedCactusGraph._super_node_name("n2", "v", "sink")) should_exist = (ExtendedCactusGraph._super_node_name( ("n1", "n2"), "w", "layer"), ExtendedCactusGraph._super_node_name("n2", "w", "sink")) eg = ExtendedCactusGraph(req, sub) for u in eg.nodes: print u for e in eg.edges: print e assert should_not_exist not in eg.edges, "Extended graph contained edge corresponding to infeasible node mapping in path" assert should_exist in eg.edges, "Extended graph did not contain edge corresponding to feasible node mapping"
def get_example_scenario_from_paper(): sub = datamodel.Substrate("sub1") request = datamodel.LinearRequest("req1") example_scenario = datamodel.Scenario("Sen1", sub, [request]) sub.add_node('v1', ["FW", "DPI"], {"FW": 2, "DPI": 1}, {"FW": 1, "DPI": 1}) sub.add_node('v2', ["FW"], {"FW": 2}, {"FW": 1}) sub.add_node('v3', ["FW", "DPI"], {"FW": 2, "DPI": 1}, {"FW": 1, "DPI": 1}) # - EDGES sub.add_edge('v1', 'v2', capacity=2) sub.add_edge('v2', 'v3', capacity=2) sub.add_edge('v3', 'v1', capacity=2) # REQUEST NODES AND EDGES request.add_node('i1', 1, "FW", allowed_nodes=["v1", "v2", "v3"]) request.add_node('i2', 1, "DPI", allowed_nodes=["v3", "v1"]) request.add_node('i3', 1, "FW", allowed_nodes=["v1"]) request.add_edge('i1', 'i2', 2) request.add_edge('i2', 'i3', 2) request.profit = 10000 return example_scenario
def test_extendedgraph_generation(): substrate = datamodel.Substrate("sub1") request = datamodel.LinearRequest("linearreq1") # REQUEST NODES AND EDGES request.add_node('i', 2, "FW") request.add_node('j', 2, "DPI") request.add_node('l', 2, "FW") request.graph['start_node'] = 'i' request.graph['end_node'] = 'j' request.add_edge('i', 'j', 2) request.add_edge('j', 'l', 2) # SUBSTRATE: - NODES substrate.add_node('u', ["FW"], {"FW": 1}, {"FW": 1}) substrate.add_node('v', ["FW"], {"FW": 1}, {"FW": 1}) substrate.add_node('w', ["DPI"], {"DPI": 1}, {"DPI": 1}) # - EDGES # - EDGES substrate.add_edge('u', 'v') substrate.add_edge('v', 'w') substrate.add_edge('u', 'w') # generation ext_graph = extendedgraph.ExtendedGraph(request, substrate) assert len(ext_graph.edges) == 17 print(ext_graph)
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 setup(self): self.substrate = datamodel.Substrate("sub1") self.request = datamodel.Request("req1") self.scenario = datamodel.Scenario("Sen1", self.substrate, [self.request])
def setup(self): self.substrate = datamodel.Substrate("substrate1")
def test_handmade_example_containing_multiple_mappings(self): req = datamodel.Request("test_req") req.add_node("i", 1.0, "t1", allowed_nodes=["w"]) req.add_node("j", 1.0, "t1", allowed_nodes=["v", "w"]) req.add_node("k", 1.0, "t1", allowed_nodes=["u"]) req.add_node("l", 1.0, "t1", allowed_nodes=["u", "v"]) req.add_edge("i", "j", 1.0) req.add_edge("j", "k", 1.0) req.add_edge("i", "k", 1.0) req.add_edge("j", "l", 1.0) req.graph["root"] = "i" sub = datamodel.Substrate("test_sub") sub.add_node("u", ["t1"], {"t1": 100}, {"t1": 100}) sub.add_node("v", ["t1"], {"t1": 100}, {"t1": 100}) sub.add_node("w", ["t1"], {"t1": 100}, {"t1": 100}) sub.add_edge("u", "v", 1000.0, bidirected=True) sub.add_edge("v", "w", 1000.0, bidirected=True) sub.add_edge("w", "u", 1000.0, bidirected=True) ext_graph = extendedcactusgraph.ExtendedCactusGraph(req, sub) # print util.get_graph_viz_string(ext_graph) # print "\n".join(str(e) for e in ext_graph.nodes) # print "\n".join(str(e) for e in ext_graph.edges) flow_values = { 'embedding': 1.0, 'node': { 'i': { 'w': 1.0 }, 'j': { 'v': 0.5, 'w': 0.5 }, 'k': { 'u': 1.0 }, 'l': { 'v': 0.5, 'u': 0.5 } }, 'edge': { ('w_[i]_+', 'w_[ij]_[u]'): 1.0, ('w_[ij]_[u]', 'w_[jk]_[u]'): 0.5, ('w_[ij]_[u]', 'v_[ij]_[u]'): 0.5, ('v_[ij]_[u]', 'v_[jk]_[u]'): 0.5, ('v_[jk]_[u]', 'u_[jk]_[u]'): 0.5, ('w_[jk]_[u]', 'u_[jk]_[u]'): 0.5, ('u_[jk]_[u]', 'u_[k]_-'): 1.0, ('v_[j]_+', 'v_[jl]'): 0.5, ('w_[j]_+', 'w_[jl]'): 0.5, ('v_[jl]', 'v_[l]_-'): 0.5, ('w_[jl]', 'u_[jl]'): 0.5, ('u_[jl]', 'u_[l]_-'): 0.5, ('w_[i]_+', 'w_[ik]_[u]'): 1.0, ('w_[ik]_[u]', 'u_[ik]_[u]'): 1.0, ('u_[ik]_[u]', 'u_[k]_-'): 1.0, } } decomposition = modelcreator_ecg_decomposition.Decomposition( req, sub, flow_values, 0.0001, 0.0001, 1e-10) mappings = decomposition.compute_mappings() assert len(mappings) == 2 expected_flow_values = [0.5, 0.5] for m, flow, load in mappings: best_matching_value = min( (expected for expected in expected_flow_values), key=lambda expected: abs(expected - flow)) expected_flow_values.remove(best_matching_value) assert flow == pytest.approx(best_matching_value)
def test_exclude_edge_mappings_with_insufficient_resources_cycle(self): sub = datamodel.Substrate("test_substrate") sub.add_node("u", ["t1", "t2"], { "t1": 100, "t2": 100 }, { "t1": 0.0, "t2": 0.0 }) sub.add_node("v", ["t1", "t2"], { "t1": 100, "t2": 100 }, { "t1": 0.0, "t2": 0.0 }) sub.add_node("w", ["t1", "t2"], { "t1": 100, "t2": 100 }, { "t1": 0.0, "t2": 0.0 }) sub.add_edge("w", "u", capacity=10.0, bidirected=False) sub.add_edge("v", "w", capacity=50.0, bidirected=False) sub.add_edge("u", "v", capacity=100.0, bidirected=False) req = datamodel.Request("test_request") req.graph["root"] = "n1" req.add_node("n1", 10.0, "t1", allowed_nodes=["u", "v", "w"]) req.add_node("n2", 10.0, "t2", allowed_nodes=["u", "v", "w"]) req.add_node("n3", 10.0, "t1", allowed_nodes=["w"]) req.add_edge("n1", "n2", 1.0) req.add_edge("n2", "n3", 50.0) req.add_edge("n1", "n3", 100.0) eg = ExtendedCactusGraph(req, sub) from alib.util import get_graph_viz_string print get_graph_viz_string(eg) should_not_exist = [ (ExtendedCactusGraph._super_node_name(("n2", "n3"), "w", "layer_cycle", branch_substrate_node="w"), ExtendedCactusGraph._super_node_name(("n2", "n3"), "u", "layer_cycle", branch_substrate_node="w")), (ExtendedCactusGraph._super_node_name(("n1", "n3"), "w", "layer_cycle", branch_substrate_node="w"), ExtendedCactusGraph._super_node_name(("n1", "n3"), "u", "layer_cycle", branch_substrate_node="w")), (ExtendedCactusGraph._super_node_name(("n1", "n3"), "v", "layer_cycle", branch_substrate_node="w"), ExtendedCactusGraph._super_node_name(("n1", "n3"), "w", "layer_cycle", branch_substrate_node="w")), ] should_exist = [ (ExtendedCactusGraph._super_node_name(("n2", "n3"), "u", "layer_cycle", branch_substrate_node="w"), ExtendedCactusGraph._super_node_name(("n2", "n3"), "v", "layer_cycle", branch_substrate_node="w")), (ExtendedCactusGraph._super_node_name(("n2", "n3"), "v", "layer_cycle", branch_substrate_node="w"), ExtendedCactusGraph._super_node_name(("n2", "n3"), "w", "layer_cycle", branch_substrate_node="w")), (ExtendedCactusGraph._super_node_name(("n1", "n3"), "u", "layer_cycle", branch_substrate_node="w"), ExtendedCactusGraph._super_node_name(("n1", "n3"), "v", "layer_cycle", branch_substrate_node="w")), ] for e in should_exist: assert e in eg.edges for e in should_not_exist: assert e not in eg.edges
def test_exclude_node_mappings_with_insufficient_resources_cycle(self): # check for a cycle sub = datamodel.Substrate("test_substrate") sub.add_node("u", ["t1", "t2"], { "t1": 100, "t2": 100 }, { "t1": 0.0, "t2": 0.0 }) sub.add_node("v", ["t1", "t2"], { "t1": 100, "t2": 0.0 }, { "t1": 0.0, "t2": 0.0 }) sub.add_node("w", ["t1", "t2"], { "t1": 100, "t2": 100 }, { "t1": 0.0, "t2": 0.0 }) sub.add_node("x", ["t1"], {"t1": 1.0}, {"t1": 0.0}) sub.add_edge("u", "v", capacity=1000, bidirected=False) sub.add_edge("v", "w", capacity=1000, bidirected=False) sub.add_edge("w", "u", capacity=1000, bidirected=False) sub.add_edge("w", "x", capacity=1000, bidirected=False) req = datamodel.Request("test_request") req.graph["root"] = "n1" req.add_node("n1", 10.0, "t1", allowed_nodes=["u"]) req.add_node("n2", 10.0, "t2", allowed_nodes=["v", "w"]) req.add_node("n3", 10.0, "t1", allowed_nodes=["w"]) req.add_node("target", 10.0, "t1", allowed_nodes=["w", "x"]) req.add_edge("n1", "n2", 10.0) req.add_edge("n2", "target", 10.0) req.add_edge("n1", "n3", 10.0) req.add_edge("n3", "target", 10.0) eg = ExtendedCactusGraph(req, sub) should_not_exist = (ExtendedCactusGraph._super_node_name( ("n1", "n2"), "v", "layer_cycle", branch_substrate_node="w"), ExtendedCactusGraph._super_node_name( ("n2", "target"), "v", "layer_cycle", branch_substrate_node="w")) should_exist = (ExtendedCactusGraph._super_node_name( ("n1", "n2"), "w", "layer_cycle", branch_substrate_node="w"), ExtendedCactusGraph._super_node_name( ("n2", "target"), "w", "layer_cycle", branch_substrate_node="w")) print should_not_exist print should_exist for u in eg.nodes: print u for e in eg.edges: print e assert should_exist in eg.edges, "Extended graph did not contain edge corresponding to feasible node mapping" assert should_not_exist not in eg.edges, "Extended graph contained edge corresponding to infeasible node mapping in cycle" should_not_exist = ExtendedCactusGraph._super_node_name( ("n1", "n2"), "v", "layer_cycle", branch_substrate_node="x") should_exist = ExtendedCactusGraph._super_node_name( ("n1", "n2"), "v", "layer_cycle", branch_substrate_node="w") assert should_not_exist not in eg.nodes, "Extended graph contained edge corresponding to infeasible node mapping in cycle"