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)
예제 #3
0
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)
예제 #6
0
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)
예제 #8
0
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
예제 #9
0
 def __init__(self):
     self.root = N.Node()