Beispiel #1
0
    def path(self, source, target):
        if source == target:
            return
        starting_source, starting_target = source, target
        vertices_seen = set([source, target])
        s_iter = self.__parent_edge.get(source)
        t_iter = self.__parent_edge.get(target)
        s_path, t_path = [], []
        while s_iter != t_iter:
            if s_iter is not None:
                s_path.append(s_iter)
                source = other_vertex(s_iter, source)
                if source in vertices_seen:
                    break
                vertices_seen.add(source)
                s_iter = self.__parent_edge.get(source)

            if t_iter is not None:
                t_path.append(t_iter)
                target = other_vertex(t_iter, target)
                if target in vertices_seen:
                    break
                vertices_seen.add(target)
                t_iter = self.__parent_edge.get(target)

        if s_iter is None and t_iter is None:
            raise NoPathExistsError

        if source == starting_target or source == target:
            for edge in s_path:
                yield reverse_edge(edge)
        if target == starting_source or source == target:
            for edge in reversed(t_path):
                yield edge
Beispiel #2
0
 def remove_vertex(self, v):
     if v not in self.__parent_edge:
         raise VertexNotFoundError(v)
     parent_edge = self.__parent_edge.pop(v)
     if parent_edge is not None:
         parent = other_vertex(parent_edge, v)
         self.__child_edges[parent].remove(parent_edge)
     for edge in self.__child_edges[v]:
         self.__parent_edge[other_vertex(edge, v)] = None
     del self.__child_edges[v]
 def path(v,w):
     if v == w:
         return [v]
     v_mate = other_vertex(matching[v], v)
     if vertex_state[v] == EVEN:
         return [v, v_mate] + \
                path(forest.get_tree(v_mate).parent().vertex, w)
     else: #vertex_state[v] == ODD
         x = bridge[v][0]
         y = other_vertex(bridge[v][1], bridge[v][0])
         return [v] + [i for i in reversed(path(x, v_mate))] + path(y,w)
Beispiel #4
0
def make_tree(graph, source, edge_weight = None):
    parent = ydict(backend=graph)
    heap = yheap(backend=graph)
    distance = ydict(backend=graph)
    
    u, distance[u] = source, 0
    while True:
        for e in graph.edges(source = u):
            if edge_weight[e] < 0:
                raise NegativeEdgeWeightError(e)
            v = other_vertex(e,u)
            distance_to_v = distance.get(v)
            relaxed_length = distance[u] + edge_weight[e]
            if distance_to_v is None or relaxed_length < distance_to_v:
                parent[v] = e
                distance[v] = relaxed_length
                if v in heap:
                    heap.modifykey(v, relaxed_length)
                else:
                    heap.insert(v, relaxed_length)

        try:
            u = heap.deletemin()
        except:
            return parent
def make_tree(graph, source, edge_weight = None):
    parent = ydict(backend=graph)
    distance = ydict(backend=graph)
    queue = ydeque(backend=graph)
    queue_members = ydict(backend=graph)

    queue.append(source)
    queue_members[source] = True
    distance[source] = 0
    curr_pass = 0
    curr_last = source

    num_vertices = sum(1 for v in graph.vertices())

    while queue:
        v = queue.popleft()
        del queue_members[v]
        for e in graph.edges(source = v):
            w = other_vertex(e, v)
            dw, dv, e_weight = distance.get(w), distance[v], edge_weight[e]
            if dw is None or dv + e_weight < dw:
                distance[w] = dv + e_weight
                parent[w] = e
                if w not in queue_members:
                    queue.append(w)
                    queue_members[w] = True
        if v == curr_last and queue:
            curr_pass += 1
            curr_last = queue[-1]
        if curr_pass >= num_vertices:
            raise NegativeCycleError
    return parent
Beispiel #6
0
 def split(self, v):
     """
     Given a vertex u, remove the edge from u to u's parent so
     they are in separate trees
     """
     edge = self.__parent_edge.get(v)
     if edge is None:
         return
     w = other_vertex(edge, v)
     self.__parent_edge[v] = None
     self.__child_edges[w].remove(edge)
Beispiel #7
0
 def reroot(self, v):
     current_node = v
     deferred_edges = list()
     
     while self.__parent_edge[current_node] is not None:
         parent_edge = self.__parent_edge[current_node]
         self.split(current_node)
         deferred_edges.append(reverse_edge(parent_edge))
         current_node = other_vertex(parent_edge, current_node)
     
     for edge in deferred_edges:
         self.add_edge(*edge)
Beispiel #8
0
    def __call__(self, **kwargs):
        if self.tree_type == "from_source":
            v = kwargs["target"]
        else:
            v = kwargs["source"]

        # TODO: simplify this mess
        edges = []
        while self.tree.get(v) is not None:
            edges.append(self.tree[v])
            v = other_vertex(self.tree[v], v)
        if self.tree_type == "from_source":
            for e in reversed(edges):
                yield e
        else:
            for e in edges:
                yield reverse_edge(e)
Beispiel #9
0
    def walkup(self, v):
        
        PRINT('--- Starting walkup from %s ---' % v, 1)
        PRINT('--- edges to consider: %s ---' % \
                  [e for e in self.g.edges(source=v)])
        for e in self.g.edges(source = v):
            w = other_vertex(e, v)
            PRINT('Looking at (v,w) = (%s,%s)' % (v,w), 4)
            if v == w:
                self.self_loops.append(e)
                continue
            
            if self.vis.DiscoverTime[w] < self.vis.DiscoverTime[v] or \
               e == self.vis.ParentEdge[w]:
                continue

            self.backedges[w].append(e)
            timestamp = self.vis.DiscoverTime[v]
            self.backedge_flag[w] = timestamp

            for face_itr in chain((w,),self.first_face_iter(w)):
                PRINT('Traveler: %s' % face_itr)
                if face_itr == v or self.visited[face_itr] == timestamp:
                    break
                elif self.is_bicomp_root(face_itr):
                    PRINT('Setting visited/pertinent roots for %s' % face_itr)
                    dfs_child = self.canonical_df_child[face_itr]
                    parent = self.vis.Parent.get(dfs_child, dfs_child)
                    handle = self.df_face_handle[dfs_child]
                    PRINT('Handle: %s' % handle)
                    if handle.vertex is not None:
                        self.visited[handle.first_endpoint()] = timestamp
                        self.visited[handle.second_endpoint()] = timestamp

                    v_df_number = self.vis.DiscoverTime[v]
                    if self.vis.LowPoint[dfs_child] < v_df_number or \
                       self.vis.LeastAncestor[dfs_child] < v_df_number:
                        PRINT('Appending %s to %s''s prs' % (handle, parent))
                        self.pertinent_roots[parent].append(handle)
                    else:
                        PRINT("Prepending %s to %s's prs" % (handle, parent))
                        self.pertinent_roots[parent].insert(0,handle)
                self.visited[face_itr] = timestamp

        PRINT('--- Done with walkup from %s ---' % v, 1)    
        PRINT('Visited: %s' % self.visited, 1)
def find_augmenting_path(g, initial_matching = None):
    vertex_state = dict()
    if initial_matching is None:
        matching = dict()
    else:
        matching = initial_matching
    even_edges = list()
    forest = tree.Forest(Vertices = g.vertices())
    blossoms = UnionFind(g.vertices())
    origin = dict((v,v) for v in g.vertices())
    bridge = dict()
        
    for v in g.vertices():
        if v not in matching:
            vertex_state[v] = EVEN
            for e in g.adjacent_edges(v):
                even_edges.append((v,other_vertex(e,v),e))
        else:
            vertex_state[v] = UNREACHED
            
    augmenting_path_edge = None
    while even_edges:
                
        u,v,current_edge \
           = even_edges.pop(int(random.uniform(0,len(even_edges))))
        u_prime = origin[blossoms.find(u)]
        v_prime = origin[blossoms.find(v)]
        
        if vertex_state[v_prime] == UNREACHED:
            vertex_state[v_prime] = ODD;
            v_prime_mate = other_vertex(matching[v_prime], v_prime)
            vertex_state[v_prime_mate] = EVEN;
            forest.add_edge(parent = u, 
                            child = v_prime, 
                            parent_edge = current_edge
                            )
            forest.add_edge(parent = v_prime, 
                            child = v_prime_mate, 
                            parent_edge = matching[v_prime]
                            )
            for e in g.adjacent_edges(v_prime_mate):
                even_edges.append((v_prime_mate,
                                   other_vertex(e,v_prime_mate),e))

        elif vertex_state[v_prime] == EVEN and u_prime != v_prime:
            try:
                nca = forest.nearest_common_ancestor(u_prime, v_prime)
            except tree.VertexNotFound:
                nca = None
            if nca is None:
                augmenting_path_edge = current_edge
                break
            for x in (u_prime, v_prime):
                prev_vertex = None
                for y in forest.get_tree(x).path_to_root():
                    if y == nca:
                        break
                    curr_vertex = origin[blossoms.find(y.vertex)]
                    if curr_vertex == prev_vertex:
                        continue
                    blossoms.link(curr_vertex, nca.vertex)
                    bridge[curr_vertex] = (x, current_edge)
                    prev_vertex = curr_vertex
            origin[blossoms.find(nca.vertex)] = nca.vertex
    
    def path(v,w):
        if v == w:
            return [v]
        v_mate = other_vertex(matching[v], v)
        if vertex_state[v] == EVEN:
            return [v, v_mate] + \
                   path(forest.get_tree(v_mate).parent().vertex, w)
        else: #vertex_state[v] == ODD
            x = bridge[v][0]
            y = other_vertex(bridge[v][1], bridge[v][0])
            return [v] + [i for i in reversed(path(x, v_mate))] + path(y,w)
    
    if augmenting_path_edge:
        x = g.source(augmenting_path_edge)
        y = g.target(augmenting_path_edge)
        x_up = path(x, forest.get_tree(x).get_root().vertex)
        y_up = path(y, forest.get_tree(y).get_root().vertex)
        print [i for i in reversed(x_up)] + y_up
        
        matching[g.source(augmenting_path_edge)] = augmenting_path_edge
        matching[g.target(augmenting_path_edge)] = augmenting_path_edge
        for path in (x_up,y_up):
            for x,y in izip(islice(path,1,None,2),islice(path,2,None,2)):
                matching[x] = matching[y] = forest.get_tree(x).parent_edge
        return matching