def labelMobileDet( M, odd, parent ): ''' labelMobileDet( M, odd, parent ) In: M is a mobile. odd and parent are vertices in M. {odd,parent} is an edge in M. odd is of an odd generation (and thus, parent is of even generation). parent has already been given a label. Out: All descendants of odd of even generation have been given a label by the (-1)-rule. ''' # The labels are determined by the label of odd's parent. parentLabel = M.node[parent][ 'label' ] # The children to be labeled. children = graphUtil.childrenOf( odd, M, parent ) # Make sure that the children get the labels in the correct order. children.sort() # Label odd's children. for i in range(len( children )): v = children[i] # The next vertex gets a label that is # one less than the preceding vertex. M.node[v][ 'label' ] = parentLabel - i - 1 # Find all children of v (they are of an odd generation) # and label them. childrenOf_v = graphUtil.childrenOf( v, M, odd ) for child_v in childrenOf_v: labelMobileDet( M, child_v, v )
def relabelTree( T, root ): ''' S = relabelTree( T, root ) In: T is a tree with vertices 0, 1, ..., n-1 and root is a vertex in T. Each vertex in T has an integer 'age' attribute such that siblings have different ages. We take siblings to be drawn in ascending order by age from left to right in the plane. Out: S is a new tree that is just like T, except the vertices have been relabeled to 0, 1, ..., n-1 such that the root is 0 and for each vertex its children are in ascending order from left to right, all vertices in generation <=k are smaller than all vertices in generation >k (for all k). ''' n = nx.number_of_nodes( T ) # Dictionary for the new labels. newLabels = dict(zip( range(n), range(n) )) nextLabel = 0 Q = Queue.Queue( maxsize = n ) Q.put( ( root, None ) ) while not Q.empty(): # We have found labels for all the nextLabel vertices # that are not descendants of the vertices in the queue Q. # The next vertex, node, gets the next number. node, parent = Q.get() newLabels[node] = nextLabel nextLabel = nextLabel + 1 # Put each child of node on the queue in ascending order by age. children = graphUtil.childrenOf( node, T, parent ) children.sort( key = lambda child: T.node[child][ 'age' ] ) for child in children: Q.put( ( child, node ) ) # Relabel the vertices according to the dictionary. return nx.relabel_nodes( T, newLabels )
def findContourSequence( contSeq, T, node, parent ): ''' findContourSequence( contSeq, T, node, parent ) In: contSeq is a list T is a tree such that for each node, its children appear in ascending order from left to right in the plane. node and parent are nodes in T, except if parent == None, in which case node is the root of T. Out: node and all its descendants (assuming parent is the parent of node) have been added to contSeq (with repetition) in the order they appear in a clockwise walk around the subtree induced by node and its descendants. ''' contSeq.append( node ) children = graphUtil.childrenOf( node, T, parent ) # Ensure that the children are visited in the correct order. children.sort() # Recursively finish the objective for each child of node. for child in children: findContourSequence( contSeq, T, child, node ) # If node is not the root, walk back to its parent. if not parent is None: contSeq.append( parent )
def findContourSequence(contSeq, T, node, parent): ''' findContourSequence( contSeq, T, node, parent ) In: contSeq is a list T is a tree such that for each node, its children appear in ascending order from left to right in the plane. node and parent are nodes in T, except if parent == None, in which case node is the root of T. Out: node and all its descendants (assuming parent is the parent of node) have been added to contSeq (with repetition) in the order they appear in a clockwise walk around the subtree induced by node and its descendants. ''' contSeq.append(node) children = graphUtil.childrenOf(node, T, parent) # Ensure that the children are visited in the correct order. children.sort() # Recursively finish the objective for each child of node. for child in children: findContourSequence(contSeq, T, child, node) # If node is not the root, walk back to its parent. if not parent is None: contSeq.append(parent)
def labelMobileRand( M, odd, parent ): ''' labelMobileRand( M, odd, parent ) In: M is a mobile. odd and parent are vertices in M. {odd,parent} is an edge in M. odd is of an odd generation (and thus, parent is of even generation). parent has already been given a label. Out: All descendants of odd of even generation have been given a random label. ''' # The children to be labeled. children = graphUtil.childrenOf( odd, M, parent ) # Make sure that the children get the labels in the correct order. children.sort() n = len(children) if n == 0: return # Make use of the multinomial method to get labels # such that the differences of nearby labels are # i.i.d. # Maximum number of trials: maxiter = 999 # Probability distribution of jumps + 1: xi = lambda k: 0.5 ** ( k + 1. ) trials = 0 while True: N = graphUtil.multinomial( n + 1, xi ) K = len(N) trials += 1 # If sum( (j-1)*N[j] ) == 0, then we are done. # If not, try again. if ( ( np.arange(K) - 1 ) * N ).sum() == 0: break if trials >= maxiter: raise RuntimeError('Maximum number of trials reached' +\ ' (%d). ' % maxiter +\ 'Try again or choose another' +\ 'probability distribution.') # Create a vector with N[j] copies of j # for j = 0, ..., K-1 and permute it randomly. Jumps = np.concatenate([ ( j - 1 ) * np.ones( N[j] ) for j in range(K) ]) Jumps = np.random.permutation( Jumps ).astype( int ) # Now, Jumps is a vector of n + 1 independent random variables # distributed by f(k) = 0.5^(k+2) for k >= -1 and sum(Jumps) == 0. # The labels are determined by the label of odd's parent. currentLabel = M.node[parent][ 'label' ] # Label odd's children. for i in range(len( children )): v = children[i] currentLabel = currentLabel + Jumps[i] M.node[v][ 'label' ] = currentLabel # Find all children of v (they are of an odd generation) # and label them. childrenOf_v = graphUtil.childrenOf( v, M, odd ) for child_v in childrenOf_v: labelMobileRand( M, child_v, v )