def create_join_node(self, node): left_node = ntd.Nice_Tree_Node(set(node.bag)) right_node = ntd.Nice_Tree_Node(set(node.bag)) # computes how to separate the children best_partition = [] best_partition_value = (0, 0) list_of_partitions = self.generate_partitions_with_2_blocks( set(self.graph.successors(node)), 2) for partition in list_of_partitions: new_partition_value = self.evaluate_partition(node, partition) if best_partition_value[0] == new_partition_value[0]: if best_partition_value[0] <= new_partition_value[0]: best_partition_value = new_partition_value best_partition = partition if best_partition_value[0] <= new_partition_value[0]: best_partition_value = new_partition_value best_partition = partition # assigns children to left and right node self.graph.add_edge(node, left_node) self.graph.add_edge(node, right_node) for left_child in best_partition[0]: self.graph.add_edge(left_node, left_child) self.graph.remove_edge(node, left_child) for right_child in best_partition[1]: self.graph.add_edge(right_node, right_child) self.graph.remove_edge(node, right_child) node.node_type = node.JOIN return [left_node, right_node]
def test_calculate_component_signatures_of_introduce_node(): # assemble nodes = [1, 2, 3, 4, 5, 6] #nodes = [1, 2] graph = nx.Graph() graph.add_nodes_from(nodes) graph.add_edges_from( [[node1, node2] for node2 in nodes for node1 in nodes if not node1 == node2] ) nice_td = nx.Graph() h = 3 k = 6 algo = alg.AlgorithmWorker(graph, nice_td, h, k) introduce_node = ntd.Nice_Tree_Node([2, 3, 4, 5]) #introduce_node = ntd.Nice_Tree_Node([1]) child_node = ntd.Nice_Tree_Node([2, 3, 5]) #child_node = ntd.Nice_Tree_Node([1, 2]) child_del_values = algo.find_component_signatures_of_leaf_nodes(child_node, child_node.bag) # act result = algo.calculate_component_signature_of_introduce_node(introduce_node, introduce_node.bag, child_node, child_node.bag, child_del_values) print(result)
def make_nice_tree_nodes(self): graph = nx.DiGraph() node_pair_dict = {} for node in list(self.graph.nodes): gnode = ntd.Nice_Tree_Node(set(node)) node_pair_dict[node] = gnode graph.add_node(gnode) for node in node_pair_dict: for edge in list(self.graph.edges(node)): graph.add_edge(node_pair_dict[edge[0]], node_pair_dict[edge[1]]) self.graph = graph self.graph_root = node_pair_dict[self.graph_root]
def test_find_component_signatures_of_join_nodes(): # assemble nodes = [1, 2, 3, 4, 5, 6] graph = nx.Graph() graph.add_nodes_from(nodes) graph.add_edges_from( [[node1, node2] for node2 in nodes for node1 in nodes if not node1 == node2] ) nice_tree_decomposition = nx.Graph() h = 3 k = 5 algo = alg.AlgorithmWorker(graph, nice_tree_decomposition, h, k) TD_join_node = ntd.Nice_Tree_Node([2, 3, 4, 5]) TD_child_node_1 = ntd.Nice_Tree_Node([1, 2, 3, 4, 5]) TD_child_node_1_del_k = algo.find_component_signatures_of_leaf_nodes(TD_child_node_1, TD_child_node_1.bag) TD_child_node_3 = ntd.Nice_Tree_Node([2,3,4,5]) TD_child_node_3_del_k = algo.find_component_signatures_of_forget_node(TD_child_node_3, TD_child_node_1, TD_child_node_1_del_k) TD_child_node_2 = ntd.Nice_Tree_Node([2, 3, 4, 5]) TD_child_node_2_del_k = algo.find_component_signatures_of_leaf_nodes(TD_child_node_2, TD_child_node_2.bag) # merge both dictionaries TD_child_node_2_del_k.update(TD_child_node_3_del_k) del_values_child = TD_child_node_2_del_k #print(del_values_child) # act result = algo.find_component_signatures_of_join_nodes(TD_join_node, TD_join_node.bag, TD_child_node_3, TD_child_node_2, del_values_child) # assert (lol) for key, del_value in result.items(): print(del_value) assert False
def test_find_component_signatures_of_leaf_nodes(): # assemble nodes = [1, 2, 3, 4, 5, 6] graph = nx.Graph() graph.add_nodes_from(nodes) graph.add_edges_from( [[node1, node2] for node2 in nodes for node1 in nodes if not node1 == node2] ) nice_tree_decomposition = nx.Graph() h = 3 k = 6 algo = alg.AlgorithmWorker(graph, nice_tree_decomposition, h, k) bag = ntd.Nice_Tree_Node([2, 3, 4, 5]) #act result = algo.find_component_signatures_of_leaf_nodes(bag, bag.bag)
def create_forget_nodes(self, node): child = list(self.graph.successors(node))[0] child_without_parent = child.bag.difference(node.bag) last_node = node if not set() == child_without_parent: for vertex in child_without_parent: parent = last_node temp = set(parent.bag) temp.add(vertex) last_node = ntd.Nice_Tree_Node(temp) self.graph.add_edge(parent, last_node) parent.node_type = parent.FORGET self.graph.remove_node(last_node) self.graph.add_edge(parent, child) self.graph.remove_edge(node, child) node.node_type = node.FORGET return node
def test_create_forget_node(): test_td = td.Tree_Decomposer(nx.complete_graph(2)) test_graph = nx.DiGraph() test_root = frozenset({1, 2, 3, 4, 5}) nodes_dict = {} nodes_dict[frozenset(test_root)] = ntd.Nice_Tree_Node(test_root) nodes_dict[frozenset({1, 2})] = ntd.Nice_Tree_Node({1, 2}) nodes_dict[frozenset({3})] = ntd.Nice_Tree_Node({3}) nodes_dict[frozenset({1, 3})] = ntd.Nice_Tree_Node({1, 3}) nodes_dict[frozenset({2, 3})] = ntd.Nice_Tree_Node({2, 3}) nodes_dict[frozenset({1, 2, 3})] = ntd.Nice_Tree_Node({1, 2, 3}) nodes_dict[frozenset({4, 5})] = ntd.Nice_Tree_Node({4, 5}) # test 1 # checks if the function creates the correct forget nodes for # 1 child and more than 1 vertex in parent that is not he child test_graph.clear() test_graph.add_edge(nodes_dict[frozenset({1, 2, 3})], nodes_dict[frozenset(test_root)]) test_td.graph = test_graph test_td.graph_root = nodes_dict[frozenset({1, 2, 3})] test_td.create_forget_nodes(nodes_dict[frozenset({1, 2, 3})]) child = list(test_td.graph.successors(nodes_dict[frozenset({1, 2, 3})]))[0] assert not child == nodes_dict[frozenset( test_root)], "this child should be removed" assert (child.bag == {1, 2, 3, 4} or child.bag == {1, 2, 3, 5}), "child has not specified bag" child_child = list(test_td.graph.successors(child))[0] assert child_child == nodes_dict[frozenset( test_root)], "last node should be child" assert child_child.bag == {1, 2, 3, 4, 5}, "child_child has not specified bag" for node_deg in list(nx.degree(test_td.graph)): assert not node_deg[1] == 0, "does create isolated node(s)" assert nx.number_of_selfloops(test_td.graph) == 0, "creates self loop(s)" assert nx.is_weakly_connected(test_td.graph), "not weakly connected"
def create_introduce_nodes(self, node): last_node = node children_of_node = list(self.graph.successors(node)) union_of_children = set() for child in set(self.graph.successors(node)): union_of_children = union_of_children.union(child.bag) node_without_children = set(node.bag).difference(union_of_children) if not set() == node_without_children: vertex = list(node_without_children).pop(0) temp = set(node.bag) temp.remove(vertex) new_parent = ntd.Nice_Tree_Node(temp) self.graph.add_edge(node, new_parent) for child in children_of_node: self.graph.add_edge(new_parent, child) self.graph.remove_edge(node, child) node.node_type = node.INTRODUCE return node
def test_create_introduce_node(): test_td = td.Tree_Decomposer(nx.complete_graph(2)) test_graph = nx.DiGraph() test_root = frozenset({1, 2, 3, 4, 5}) nodes_dict = {} nodes_dict[frozenset(test_root)] = ntd.Nice_Tree_Node(test_root) nodes_dict[frozenset({1, 2})] = ntd.Nice_Tree_Node({1, 2}) nodes_dict[frozenset({3})] = ntd.Nice_Tree_Node({3}) nodes_dict[frozenset({1, 3})] = ntd.Nice_Tree_Node({1, 3}) nodes_dict[frozenset({2, 3})] = ntd.Nice_Tree_Node({2, 3}) nodes_dict[frozenset({1, 2, 3})] = ntd.Nice_Tree_Node({1, 2, 3}) nodes_dict[frozenset({4, 5})] = ntd.Nice_Tree_Node({4, 5}) # test 1 # checks if the function creates the correct introduce nodes for # more than 1 child and more than 1 vertex in parent that is in neither of the children test_graph.clear() test_graph.add_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({1, 2})]) test_graph.add_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({3})]) test_graph.add_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({1, 3})]) test_graph.add_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({2, 3})]) test_td.graph = test_graph test_td.graph_root = nodes_dict[frozenset(test_root)] test_td.create_introduce_nodes(nodes_dict[frozenset(test_root)]) child = list(test_td.graph.successors(nodes_dict[frozenset(test_root)]))[0] assert (child.bag == {1, 2, 3, 4} or child.bag == {1, 2, 3, 5}), "child has not specified bag" for node_deg in list(nx.degree(test_td.graph)): assert not node_deg[1] == 0, "does create isolated node(s)" assert nx.number_of_selfloops(test_td.graph) == 0, "creates self loop(s)" assert nx.is_weakly_connected(test_td.graph), "not weakly connected" #----------------------------------------------------------------------------------------- test_td.graph.remove_edge(test_td.graph_root, child) test_td.graph.remove_edge(child, nodes_dict[frozenset({1, 2})]) test_td.graph.remove_edge(child, nodes_dict[frozenset({3})]) test_td.graph.remove_edge(child, nodes_dict[frozenset({1, 3})]) test_td.graph.remove_edge(child, nodes_dict[frozenset({2, 3})]) assert nx.is_empty( test_td.graph ), "creates additional edge(s) or does not remove specified edge(s)" # test 2 # checks if the function correctly creates no introduce nodes for # 1 child and no vertex in parent that is not in the child test_graph.clear() test_td.graph_root = nodes_dict[frozenset(test_root)] test_graph.add_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({1, 2, 3})]) test_graph.add_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({4, 5})]) test_td.graph = test_graph test_td.create_introduce_nodes(nodes_dict[frozenset(test_root)]) for node_deg in list(nx.degree(test_td.graph)): assert not node_deg[1] == 0, "does create isolated node(s)" assert nx.number_of_selfloops(test_td.graph) == 0, "creates self loop(s)" assert nx.is_weakly_connected(test_td.graph), "not weakly connected" #----------------------------------------------------------------------------------------- test_graph.remove_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({1, 2, 3})]) test_graph.remove_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({4, 5})]) assert nx.is_empty( test_td.graph ), "creates additional edge(s) or does not remove specified edge(s)" # test 3 # checks if the function correctly creates introduce nodes for # 1 child and 1+ vertex in parent that is not in the child test_graph.clear() test_graph.add_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({1, 2, 3})]) test_td.graph = test_graph test_td.create_introduce_nodes(nodes_dict[frozenset(test_root)]) for node_deg in list(nx.degree(test_td.graph)): assert not node_deg[1] == 0, "does create isolated node(s)" assert nx.number_of_selfloops(test_td.graph) == 0, "creates self loop(s)" assert nx.is_weakly_connected(test_td.graph), "not weakly connected" #----------------------------------------------------------------------------------------- test_td.graph.remove_edge( list(test_td.graph.successors(nodes_dict[frozenset(test_root)]))[0], nodes_dict[frozenset({1, 2, 3})]) test_td.graph.remove_edge( nodes_dict[frozenset(test_root)], list(test_td.graph.successors(nodes_dict[frozenset(test_root)]))[0]) assert nx.is_empty( test_td.graph ), "creates additional edge(s) or does not remove specified edge(s)"
def test_create_join_node(): test_td = td.Tree_Decomposer(nx.complete_graph(2)) test_graph = nx.DiGraph() test_root = frozenset({1, 2, 3, 4, 5}) nodes_dict = {} nodes_dict[frozenset(test_root)] = ntd.Nice_Tree_Node(test_root) nodes_dict[frozenset({1, 2})] = ntd.Nice_Tree_Node({1, 2}) nodes_dict[frozenset({3})] = ntd.Nice_Tree_Node({3}) nodes_dict[frozenset({1, 3})] = ntd.Nice_Tree_Node({1, 3}) nodes_dict[frozenset({2, 3})] = ntd.Nice_Tree_Node({2, 3}) nodes_dict[frozenset({1, 2, 3})] = ntd.Nice_Tree_Node({1, 2, 3}) nodes_dict[frozenset({4, 5})] = ntd.Nice_Tree_Node({4, 5}) # test 1 # checks if the function creates the correct join nodes andfor # more than 2 child and more than 1 vertex in parent that is neither of the children test_graph.clear() test_graph.add_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({1, 2})]) test_graph.add_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({3})]) test_graph.add_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({1, 3})]) test_graph.add_edge(nodes_dict[frozenset(test_root)], nodes_dict[frozenset({2, 3})]) test_td.graph = test_graph test_td.graph_root = nodes_dict[frozenset(test_root)] test_td.create_join_node(nodes_dict[frozenset(test_root)]) child_left = list(test_td.graph.successors(test_td.graph_root))[0] child_right = list(test_td.graph.successors(test_td.graph_root))[1] assert child_left.bag == test_td.graph_root.bag, "left child does not have same bag as join node" assert child_right.bag == test_td.graph_root.bag, "right child does not have same bag as join node" for node_deg in list(nx.degree(test_td.graph)): assert not node_deg[1] == 0, "does create isolated node(s)" assert nx.number_of_selfloops(test_td.graph) == 0, "creates self loop(s)" assert nx.is_weakly_connected(test_td.graph), "not weakly connected" for child in [ nodes_dict[frozenset({1, 2})], nodes_dict[frozenset({3})], nodes_dict[frozenset({1, 3})], nodes_dict[frozenset({2, 3})] ]: assert test_td.graph.has_edge( child_left, child) or test_td.graph.has_edge( child_right, child), "a child is left alone D:" #----------------------------------------------------------------------------------------- if test_td.graph.has_edge(child_left, child): test_td.graph.remove_edge(child_left, child) if test_td.graph.has_edge(child_right, child): test_td.graph.remove_edge(child_right, child) test_td.graph.remove_edge(test_td.graph_root, child_right) test_td.graph.remove_edge(test_td.graph_root, child_left) assert nx.is_empty( test_td.graph ), "creates additional edge(s) or does not remove specified edge(s)"