Exemple #1
0
def pt_DFS(v):

    global G, reached

    S = Stack()

    if reached[v] == 0:
        reached[v] = 1
        S.Push(v)

    while S.IsNotEmpty():
        v = S.Pop()
        for w in G.adj_nodes(v):
            if reached[w] == 0:
                reached[w] = 1
                S.Push(w)
Exemple #2
0
def strongly_planar(e0, Att):
    # We now come to the heart of the planarity test: procedure strongly_planar.
    # It takes a tree edge e0=(x,y) and tests whether the segment S(e0) is
    # strongly planar.
    # If successful it returns (in Att) the ordered list of attachments of S(e0)
    # (excluding x); high DFS-numbers are at the front of the list.
    # In alpha it records the placement of the subsegments.
    #
    # strongly_planar operates in three phases.
    # It first constructs the cycle C(e0) underlying the segment S(e0).
    # It then constructs the interlacing graph for the segments emanating >from the
    # spine of the cycle.
    # If this graph is non-bipartite then the segment S(e0) is non-planar.
    # If it is bipartite then the segment is planar.
    # In this case the third phase checks whether the segment is strongly planar
    # and, if so, computes its list of attachments.

    global G, alpha, dfsnum, parent

    #--------------------------------------------------------------
    # DETERMINE THE CYCLE C(e0)
    # We determine the cycle "C(e0)" by following first edges until a back
    # edge is encountered.
    # |wk| will be the last node on the tree path and |w0|
    # is the destination of the back edge.
    x = source(e0)
    y = target(e0)
    e = G.first_adj_edge(y)
    wk = y

    while dfsnum[target(e)] > dfsnum[wk]:  # e is a tree edge
        wk = target(e)
        e = G.first_adj_edge(wk)
    w0 = target(e)
    #--------------------------------------------------------------

    #--------------------------------------------------------------
    # PROCESS ALL EDGES LEAVING THE SPINE
    # The second phase of |strongly_planar| constructs the connected
    # components of the interlacing graph of the segments emananating
    # from the the spine of the cycle "C(e0)".
    # We call a connected component a "block".
    # For each block we store the segments comprising its left and
    # right side (lists |Lseg| and |Rseg| contain the edges defining
    # these segments) and the ordered list of attachments of the segments
    # in the block;
    # lists |Latt| and |Ratt| contain the DFS-numbers of the attachments;
    # high DFS-numbers are at the front of the list.
    #
    # We process the edges leaving the spine of "S(e0)" starting at
    # node |wk| and working backwards.
    # The interlacing graph of the segments emanating from
    # the cycle is represented as a stack |S| of blocks.
    w = wk
    S = Stack()

    while w != x:
        count = 0
        for e in G.adj_edges(w):
            count = count + 1

            if count != 1:  # no action for first edge
                # TEST RECURSIVELY
                # Let "e" be any edge leaving the spine.
                # We need to test whether "S(e)" is strongly planar
                # and if so compute its list |A| of attachments.
                # If "e" is a tree edge we call our procedure recursively
                # and if "e" is a back edge then "S(e)" is certainly strongly
                # planar and |target(e)| is the only attachment.
                # If we detect non-planarity we return false and free
                # the storage allocated for the blocks of stack |S|.
                A = List()
                if dfsnum[w] < dfsnum[target(e)]:
                    # tree edge
                    if not (strongly_planar(e, A)):
                        while S.IsNotEmpty():
                            S.Pop()
                        return 0
                else:
                    A.append(dfsnum[target(e)])  # a back edge

                    # UPDATE STACK |S| OF ATTACHMENTS
                    # The list |A| contains the ordered list of attachments
                    # of segment "S(e)".
                    # We create an new block consisting only of segment "S(e)"
                    # (in its L-part) and then combine this block with the
                    # topmost block of stack |S| as long as there is interlacing.
                    # We check for interlacing with the L-part.
                    # If there is interlacing then we flip the two sides of the
                    # topmost block.
                    # If there is still interlacing with the left side then the
                    # interlacing graph is non-bipartite and we declare the graph
                    # non-planar (and also free the storage allocated for the
                    # blocks).
                    # Otherwise we check for interlacing with the R-part.
                    # If there is interlacing then we combine |B| with the topmost
                    # block and repeat the process with the new topmost block.
                    # If there is no interlacing then we push block |B| onto |S|.
                B = block(e, A)

                while 1:
                    if B.left_interlace(S): (S.contents[-1]).flip()
                    if B.left_interlace(S):
                        del B
                        while S.IsNotEmpty():
                            S.Pop()
                        return 0
                    if B.right_interlace(S): B.combine(S.Pop())
                    else: break
                S.Push(B)

                # PREPARE FOR NEXT ITERATION
                # We have now processed all edges emanating from vertex |w|.
                # Before starting to process edges emanating from vertex
                # |parent[w]| we remove |parent[w]| from the list of attachments
                # of the topmost
                # block of stack |S|.
                # If this block becomes empty then we pop it from the stack and
                # record the placement for all segments in the block in array
                # |alpha|.
        while (S.IsNotEmpty()
               and (S.contents[-1]).clean(dfsnum[parent[w]], alpha, dfsnum)):
            S.Pop()

        w = parent[w]
        #--------------------------------------------------------------

        #--------------------------------------------------------------
        # TEST STRONG PLANARITY AND COMPUTE Att
        # We test the strong planarity of the segment "S(e0)".
        # We know at this point that the interlacing graph is bipartite.
        # Also for each of its connected components the corresponding block
        # on stack |S| contains the list of attachments below |x|.
        # Let |B| be the topmost block of |S|.
        # If both sides of |B| have an attachment above |w0| then
        # "S(e0)" is not strongly planar.
        # We free the storage allocated for the blocks and return false.
        # Otherwise (cf. procedure |add_to_Att|) we first make sure that
        # the right side of |B| attaches only to |w0| (if at all) and then
        # add the two sides of |B| to the output list |Att|.
        # We also record the placements of the subsegments in |alpha|.
    Att.clear()

    while S.IsNotEmpty():
        B = S.Pop()

        if (not (B.empty_Latt()) and not (B.empty_Ratt())
                and B.head_of_Latt() > dfsnum[w0]
                and B.head_of_Ratt() > dfsnum[w0]):
            del B
            while S.IsNotEmpty():
                S.Pop()
            return 0
        B.add_to_Att(Att, dfsnum[w0], alpha, dfsnum)
        del B

        # Let's not forget that "w0" is an attachment
        # of "S(e0)" except if w0 = x.
    if w0 != x: Att.append(dfsnum[w0])

    return 1
Exemple #3
0
def TreeCoords(G, root, orientation):
    S = Stack()
    visited = {}
    d = {}
    leaves = []
    number_of_leaves = 0
    height = 0
    nodes = {}
    children = {}
    father = {}
    
    for v in G.vertices:
        visited[v] = 0	
    visited[root] = 1
    S.Push(root)
    d[root] = 0
    nodes[0] = []
    children[root] = []
    father[root] = None 
    
    while S.IsNotEmpty():
        v = S.Pop()
        if orientation=="vertical":
            nodes[d[v]].insert(0,v)
            if v!=root: children[father[v]].insert(0,v)
        else:
            nodes[d[v]].append(v)
            if v!=root: children[father[v]].append(v)
        isleaf = 1
        for w in G.InOutNeighbors(v):
            if visited[w] == 0:
                isleaf = 0
                visited[w] = 1
                d[w] = d[v] + 1
                children[w] = []
                father[w] = v
                if d[w]>height:
                    height = d[w]
                    nodes[height] = []
                S.Push(w)
        if isleaf:
            number_of_leaves = number_of_leaves + 1
            if orientation=="vertical":
                leaves.insert(0,v)
            else:
                leaves.append(v)
                
                # Test whether the graph is connected and
                # acyclic.(=test whether the graph is a tree)
    for v in G.vertices:
    
        if visited[v]==0:
            showwarning("Warning", 
                        "Graph is not a tree,\n"
                        "not connected !!!")
            return 0
            
        ch_len = len(children[v])
        if v!=root: ch_len = ch_len + 1
        if ch_len<len(G.InOutNeighbors(v)):
            showwarning("Warning", 
                        "Graph is not a tree,\n"
                        "contains cycles !!!")                
            return 0
            
            
    if number_of_leaves<=19:
        dist1 = 50
    else:
        dist1 = 900 / (number_of_leaves-1)
        
    if height+1<=19:
        dist2 = 50
    else:
        dist2 = 900 / height
        
    if dist1<25 or dist2<30: 
        showwarning("Warning", 
                    "Tree-Layout not possible,\n"
                    "the tree is too large !!!")
        return 0
        
        
    Coord1 = {}
    Coord2 = {}
    i = 0
    for v in leaves:
        Coord1[v] = 50 + i * dist1
        Coord2[v] = 50 + d[v] * dist2
        i = i + 1
        
    i = height - 1
    while i>=0:
        for v in nodes[i]:
            if children[v]!=[]:
                Coord2[v] = 50 + d[v] * dist2
                if len(children[v])==1:
                    Coord1[v] = Coord1[children[v][0]]
                else:
                    Coord1[v] = ( Coord1[children[v][0]] +
                                  (Coord1[children[v][-1]] - 
                                   Coord1[children[v][0]]) / 2)  
        i=i-1
        
    if orientation=="vertical":
        G.xCoord=Coord1
        G.yCoord=Coord2
    else:
        G.xCoord=Coord2
        G.yCoord=Coord1
        
    return 1