def aux(node): ''' Using BFS to reach all the leaves of tree, and adds empty node as a child to it if needed. Parameters: node (Node object)''' if node.children != []: for child in node.children: aux(child) else: if node.value != []: empty_node = Node() empty_node.add_parent(node)
def join_subtree(parent, children, flag): ''' Makes the tree satisfy the condition: a node cannot have more than two children, and if that's the case they should have the same value as their father. Parameters: parent (Node object) children (Node object list) flag (boolean)''' #flag is here just for us to know if we still need to remove the edges between the "original" children and their parent children = children[:] #won't work with deepcopy if not flag: flag = True for child in children: parent.delete_edge(child) if len(children) == 1: parent.add_children(children) else: #left subtree: # if the child is different from the parent, # we add a node of value parent.value between parent and child # else, we just (re)connect the child and the parent if set(children[0].value) != set(parent.value): parent_left = Node(parent.value) parent_left.add_parent(parent) children[0].add_parent(parent_left) else: children[0].add_parent(parent) #right subtree: #we start by adding the right child of the parent with the value parent.value parent_right = Node(parent.value) parent_right.add_parent(parent) #apply join_subtree on the parent_right and the remaining children join_subtree(parent_right, children[1:], flag)
def getSectionPairs(surface, sections): nodes = [] for section in sections: nodes.append(Node(section.id, section)) edges = [] for node in nodes: for otherNode in nodes: if otherNode.id <= node.id: continue section1 = node.data section2 = otherNode.data cost = getShortestIntersectionPathLength(surface, section1, section2) edges.append(Edge(cost, node.id, otherNode.id)) minimumSpanningTree = getMinimumSpanningTree(nodes, edges) sectionPairs = [] for edge in minimumSpanningTree: section1 = getNode(nodes, edge.nodeId1).data section2 = getNode(nodes, edge.nodeId2).data sectionPairs.append((section1, section2)) return sectionPairs
def canonical_path(parent, child): ''' Transforms the path between a parent and its child into a canonical one. Parameters: path is non needed, changes are to be made parent (Node object) child (Node object)''' starting_set_minus = set_substraction(parent, child) #list of char that we should get rid of as they don't appear in child.value arrival_set_minus = set_substraction(child, parent) #list of char that we should add to reach the child parent.delete_edge(child) #we substitude this edge by the new nodes temp_value = parent.value[:] former_node = parent #first step: adding forget nodes until reaching the node with value (node1.value intersect node2.value) for element in starting_set_minus: temp_value.remove(element) #waaaaaaaaaaas here actual_node = Node(temp_value[:]) actual_node.add_parent(former_node) former_node = actual_node #second step: add nodes if len(arrival_set_minus) == 0: #if node2.value included in node1.value then the former_node.value=node2.value #so no need to have the two in the path former_node.add_children(child.children) #beware, the child is no longer part of the path if len(arrival_set_minus) >= 1: # because the arrival node aka node2 is already in the tree/path: # no need to add a node that has the same value arrival_set_minus = arrival_set_minus[:-1] #second step: add nodes until reaching the node2 for element in arrival_set_minus: temp_value.append(element) actual_node = Node(temp_value[:]) actual_node.add_parent(former_node) former_node = actual_node child.add_parent(former_node)
def adding_empty_leaves(tree): ''' Adds empty leaves to the tree if needed, and if the root is non empty, adds an empty root. Parameters: tree (Tree object) ''' def aux(node): ''' Using BFS to reach all the leaves of tree, and adds empty node as a child to it if needed. Parameters: node (Node object)''' if node.children != []: for child in node.children: aux(child) else: if node.value != []: empty_node = Node() empty_node.add_parent(node) if tree.root.value != []: empty_node = Node() tree.root.add_parent(empty_node) tree.root = empty_node aux(tree.root)
def getPathBetweenPoints(surface, points): nodes = [] for i, point in enumerate(points): nodes.append(Node(i, point)) edges = [] for node in nodes: for otherNode in nodes: if otherNode.id <= node.id: continue point1 = node.data point2 = otherNode.data cost = getDistance(point1.x, point1.z, point2.x, point2.z) edges.append(Edge(cost, node.id, otherNode.id)) minimumSpanningTree = getMinimumSpanningTree(nodes, edges) paths = [] for edge in minimumSpanningTree: point1 = getNode(nodes, edge.nodeId1).data point2 = getNode(nodes, edge.nodeId2).data path = getPath(surface, point1.x, point1.z, point2.x, point2.z) paths.append(path) return paths
def nice_path(path): ''' Transforms a path (a particular case of Tree object) into a nice one. Parameters: path (Tree object)''' if path.root.value != "": #in case the root is non empty, we add an empty node as a root empty_node = Node() path.root.add_parent(empty_node) path.root = empty_node actual_node = path.root while actual_node.children != []: former_node = actual_node actual_node = former_node.children[0] #there is only a child each time canonical_path(former_node, actual_node) if actual_node.value != "": #in case the last node of the path is non empty, we add an empty node at the end former_node = actual_node empty_node = Node('') empty_node.add_parent(former_node) canonical_path(former_node, empty_node)
from Classes import Node, Tree from Path_decomposition import nice_path from Tree_decomposition import adding_join_subtree, adding_empty_leaves, adding_join_subtree, canonical_tree from Verification import is_connected, check_vertices_edges, fill_dict, is_nice_tree ####### examples on path path=[] #case0 a=Node(['a','b','c','d','e','f','g']) t=Tree(a) path.append(t) #case1 a=Node() b=Node(['a']) b.add_parent(a) c=Node(['a','b']) c.add_parent(b) d=Node(['a','b','c']) d.add_parent(c) e=Node(['a','b']) e.add_parent(d) f=Node(['a','b']) f.add_parent(e) g=Node() g.add_parent(f) t=Tree(a) path.append(t) #case2
def __init__(self): self.root = N.Node()