Example #1
0
def test_first_find(backend):
    u = UnionFind(backend=backend)
    assert u.find('a') == 'a'
    assert u.find('a') == 'a'    
    assert u.find(1) == 1
    assert u.find(1) == 1
    assert u.find(12.2) == 12.2    
    assert u.find(12.2) == 12.2
def spanning_tree_edges(graph, edge_weight):
    components = UnionFind(memory_usage=graph.MemoryUsage)
    sorted_edges = DHeap(memory_usage=graph.MemoryUsage)
    for edge in graph.edges():
        sorted_edges.insert(edge, key=edge_weight[edge])

    while sorted_edges:
        edge = sorted_edges.deletemin()
        if components.link(*edge) is not None:
            yield edge
Example #3
0
def test_link(backend):
    u = UnionFind(backend=backend)
    assert u.link(0,1) in [0,1]
    assert u.link(0,1) is None
    assert u.link(2,3) in [2,3]
    assert u.link(2,3) is None
    assert u.link(3,4) in [2,3,4]
    assert u.link(3,4) is None
    assert u.link(2,4) is None
    assert u.link(2,3) is None
    assert u.link(0,2) in [0,1,2,3,4]
    for x in xrange(5):
        for y in xrange(5):
            assert u.link(x,y) is None
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
Example #5
0
def test_find(backend):
    u = UnionFind(backend=backend)
    u.link(0,1)
    u.link(2,3)
    assert u.find(0) == u.find(1)
    assert u.find(2) == u.find(3)
    assert u.find(4) == 4
    assert u.find(0) != u.find(2)
    assert u.find(0) != u.find(4)
    assert u.find(2) != u.find(4)
    u.link(0,2)
    assert u.find(0) == u.find(1)
    assert u.find(1) == u.find(2)
    assert u.find(2) == u.find(3)
    assert u.find(3) != u.find(4)
    u.link(3,4)
    assert u.find(0) == u.find(1)
    assert u.find(1) == u.find(2)
    assert u.find(2) == u.find(3)
    assert u.find(3) == u.find(4)