def MinimumSpanningTree(self):
        """
        Return the minimum spanning tree of an undirected graph .
        self.graph should be represented in such a way that self.graph[u][v] gives the
        length of edge u,v, self.graph[u] should give the list of the neighbours,
        and self.graph[u][v] should always equal self.graph[v][u].
        self.graph should be a dictionary where each key is a vertex in the graph and
        each value is a dictionary of destination:weight pairs
        The tree is returned as a list of edge tuples.

        Should adapt to use Numpy?
        """

        # Kruskal's algorithm: sort edges by weight, and add them one at a time.
        # We use Kruskal's algorithm, first because it is very simple to
        # implement once UnionFind exists, and second, because the only slow
        # part (the sort) is sped up by being built in to Python.
        subtrees = UnionFind()
        tree = []
        
        # edges are found on initialization
        self.edges.sort()
        #print self.edges
        for W,u,v in self.edges:
            if self.verbose: print subtrees
            if subtrees[u] != subtrees[v]:
                tree.append((u,v))
                subtrees.union(u,v)
        self.m_s_tree = tree
Beispiel #2
0
    def __init__(self, parent, pairs):
        """Set up to find LCAs of pairs in tree defined by parent.
        LCA of any given pair x,y can then be found by self[x][y].
        However unlike the online LCA structure we can not find LCAs
        of pairs that are not supplied to us at startup time.
        """

        # set up dictionary where answers get stored
        dict.__init__(self)
        for u, v in pairs:
            self.setdefault(u, {})[v] = self.setdefault(v, {})[u] = None

        # set up data structure for finding node ancestor on search path
        # self.descendants forms a collection of disjoint sets,
        #    one set for the descendants of each search path node.
        # self.ancestors maps disjoint set ids to the ancestors themselves.
        self.descendants = UnionFind()
        self.ancestors = {}

        # invert the parent relationship so we can traverse the tree
        self.children = {}
        for x, px in parent.iteritems():
            self.children.setdefault(px, []).append(x)
        root = [x for x in self.children if x not in parent]
        if len(root) != 1:
            raise ValueError("LCA input is not a tree")

        # initiate depth first traversal
        self.visited = Set()
        self.traverse(root[0])
Beispiel #3
0
def MinimumSpanningTree(graph, weights):
    """
    Return the minimum spanning tree of an undirected graph G.
    G should be represented in such a way that iter(G) lists its
    vertices, iter(G[u]) lists the neighbors of u, G[u][v] gives the
    length of edge u,v, and G[u][v] should always equal G[v][u].
    The tree is returned as a list of edges.
    """
    if not isinstance(graph, UndirectedGraph):
        raise ValueError("Provided graph is not an UndirectedGraph.")
    for vertex in range(graph.n_vertices):
        for child in graph.adjacency_list[vertex]:
            if weights[vertex, child] != weights[child, vertex]:
                raise ValueError("Assymetric weights provided.")

    # Kruskal's algorithm: sort edges by weight, and add them one at a time.
    # We use Kruskal's algorithm, first because it is very simple to
    # implement once UnionFind exists, and second, because the only slow
    # part (the sort) is sped up by being built in to Python.
    subtrees = UnionFind()
    tree = []
    for W, u, v in sorted((weights[u][v], u, v)
                          for u in range(graph.n_vertices)
                          for v in graph.adjacency_list[u]):
        if subtrees[u] != subtrees[v]:
            tree.append((u, v))
            subtrees.union(u, v)
    return tree
def connectedComponentOutsidePermittedRegionBlacken(img, vstart, vend):
    labels = UnionFind()
    # pass 1
    labeled = set()
    for currentPoint in iterImg(img):
        y, x = currentPoint
        if sum(img[y, x]) <= 100:  # black
            continue
        labeled.add(currentPoint)
        neighbors = getSurrounding1(img, y, x)
        # if all 4 neighbors are black or unlabeled (ie, 0 labeled white neighbors), assign new label
        # if only 1 neighbor is white, assign its label to current point
        # if more than 1 of the neighbors are white, assign one of their labels to the current point, and note equivalence
        labeled_white_neighbors = [
            neighbor for neighbor in neighbors
            if sum(img[neighbor]) > 100 and neighbor in labeled
        ]
        if len(labeled_white_neighbors) == 0:  # assign new label
            z = labels[currentPoint]
        else:
            for neighbor in labeled_white_neighbors:
                labels.union(neighbor, currentPoint)
    # now blacklist all sets st they have a child that is in the forbidden region
    blacklist = set()
    for currentPoint in labeled:
        y, x = currentPoint
        if y < vstart or y > vend:
            blacklist.add(labels[currentPoint])
    # pass 2 - blacken blacklisted components
    for currentPoint in labeled:
        y, x = currentPoint
        curset = labels[currentPoint]
        if curset in blacklist:
            img[y, x] = (0, 0, 0)
Beispiel #5
0
def merge_cliques(m_parameters, upper_bound, rand):
    """
        Merge cliques
    """
    dis_set = UnionFind()
    [dis_set[i] for i in range(m_parameters.num_maximal_cliques)]

    final_edges = []

    # m_parameters.edges_list.sort(key=lambda e: -e[3])

    while m_parameters.edges_list and m_parameters.num_edges < upper_bound:
        (a, b, sep, omega), index = rand.next_element(m_parameters.edges_list)
        # (a, b, sep, omega), index = m_parameters.edges_list[0], 0
        del m_parameters.edges_list[index]
        i = dis_set[a]
        j = dis_set[b]
        edges_a = m_parameters.cardinality_array[i] - omega
        edges_b = m_parameters.cardinality_array[j] - omega
        if m_parameters.num_edges + (edges_a * edges_b) <= upper_bound:
            dis_set.union(a, b)
            m_parameters.cliques[i].update(m_parameters.cliques[j])
            m_parameters.cardinality_array[i] = edges_b + edges_a + omega
            m_parameters.cliques[j] = set()
            m_parameters.cardinality_array[j] = 0
            m_parameters.num_edges += edges_b * edges_a
            m_parameters.num_maximal_cliques -= 1
        else:
            final_edges.append((a, b, sep, omega))

    m_parameters.edges_list.extend(final_edges)
    for i, (start, end, sep, weight) in enumerate(m_parameters.edges_list):
        m_parameters.edges_list[i] = (dis_set[start], dis_set[end], sep,
                                      weight)
Beispiel #6
0
 def compute(self):
     #subsetList = [SubSet(i,0) for i in xrange(self.V)]
     uf = UnionFind(self.V, self.E)
     for edge in self.graph:
         if self.checkCycle(uf,edge):
             self.mst.append(edge)
             uf.union(edge.src,edge.dest)
Beispiel #7
0
def MinimumSpanningTree(V,E,W):
    """
    Return the minimum spanning tree of an undirected graph G=(V,E) with total its cost.
    W is a weights dictionary containing weight w of edge (u,v)
    as the dict entry W[(u,v)] = W[(v,u)] = w (W should be symmetric).
    The tree is returned as a list of edges.

    Notes: Kruskal's algorithm for minimum spanning 
	   Adpated from D. Eppstein' implementation (April 2006 version).
    """
    
    from UnionFind import UnionFind # used for forests manipulation
    # Kruskal's algorithm: sort edges by weight, and add them one at a time.
    # We use Kruskal's algorithm, first because it is very simple to
    # implement once UnionFind exists, and second, because the only slow
    # part (the sort) is sped up by being built in to Python.
    subtrees = UnionFind()
    tree = []
    #edges = [(G[u][v],u,v) for u in G for v in G[u]]
    edges = [(W[(u,v)],u,v) for (u,v) in E]
    edges.sort()
    cost = 0.0
    for w,u,v in edges:
        if subtrees[u] != subtrees[v]:
            tree.append((u,v))
            subtrees.union(u,v)
	    cost+=w
    return (tree,cost)
    def testFind(self):
        elements = [1,2,3,4,5,6,7]
        uf = UnionFind(elements)

        self.assertEqual(uf.find(1), 1)
        self.assertEqual(uf.find(6), 6)
        self.assertNotEqual(uf.find(7), 5)
def KruskalMST(graph:EdgeWeightedGraph):

    MST = []
    EdgeSequence=[]
    UF = UnionFind(graph.numVertices())

    #Pre-processing the edges
    PQ = []
    for item in graph.adj:
        PQ += graph.adj[item]
    heapq.heapify(PQ)

    while (len(PQ)>0) & (len(MST) < graph.numVertices()-1):
        e = heapq.heappop(PQ)
        v = e.either()
        w = e.other(v)

        if (UF.connected(v,w)):
            continue
        else:
            UF.union(v,w)
            heapq.heappush(MST, e)
            EdgeSequence.append(e)

        cluster = set()
        for item in UF.id:
            cluster.add(item)

        print ("cluster:", cluster, len(cluster))
        print (e.weight)
    return MST
Beispiel #10
0
    def __getTree(self):
        # Sort edges by decreasing pheromone levels
        self.edgeInfos.sort(key=geteiPheromoneLevel, reverse=True)
        start = 0
        # Current edges that will be inspected
        C = []
        # Data structure for Kruskal's algorithm
        subtrees = UnionFind()
        solution = []
        degrees = defaultdict(int)  # Map of degrees for each vertice

        # While we don't have n-1 edges in our solution
        while len(solution) != self.n - 1:
            # Pick the the next nCanditates edges
            C = self.edgeInfos[start:start + self.nCandiates]

            # Sort the edge selection by increasing cost
            C.sort(key=geteiCost)
            start += self.nCandiates

            for ei in C:
                u, v = ei.u, ei.v
                # Test if edge can be added to the current solution
                if subtrees[u] != subtrees[v] and \
                   degrees[u] < self.d and degrees[v] < self.d:  # Check constraint
                    solution.append(ei)
                    # Increment degrees of vertices of the added edge
                    degrees[u] += 1
                    degrees[v] += 1
                    # Update subtrees
                    subtrees.union(u, v)
        return solution
Beispiel #11
0
    def test(self):
        uf = UnionFind()
        uf.union('alpha', 'bravo', 'charlie', 'delta')
        uf.consolidate(mysql_db, mysql_table, role='player', type='individual')
        for el in self._select_star():
            self.assertSetEqual(
                set(['role', 'type', '_id', 'parent', 'weight']),
                set(el.keys()))
            self.assertEqual(el['role'], 'player')
            self.assertEqual(el['type'], 'individual')

        uf = UnionFind(mysql_db,
                       mysql_table,
                       'mysql',
                       role='player',
                       type='organization')
        uf.union('adams', 'boston', 'chicago')
        for el in self._select_star():
            if el['type'] == 'organization':
                self.assertIn(el['_id'], ['adams', 'boston', 'chicago'])
            elif el['type'] == 'individual':
                self.assertIn(el['_id'],
                              ['alpha', 'bravo', 'charlie', 'delta'])
            else:
                raise self.failureException
Beispiel #12
0
def foodHeuristic(state, problem):
    position, foodGrid = state
    "*** YOUR CODE HERE ***"
    nodes = foodGrid.asList()
    nodes.append(position)
    
    G = {}
    for p1 in nodes:
        for p2 in nodes:
            dist1 = p1,p2
            dist2 = p2,p1
            if p1<p2:
                if dist1 in problem.heuristicInfo:
                    dist = problem.heuristicInfo[dist1]
                elif dist2 in problem.heuristicInfo:
                    dist = problem.heuristicInfo[dist2]
                else:
                    dist = mazeDistanceAStar(p1, p2, problem.getStartingGameState())
                    #dist = manDistance(p1, p2)
                    problem.heuristicInfo[p1,p2] = dist
                G[p1,p2] = G[p2,p1] = dist
                    
            if p1 == p2:
                G[p1,p2] = 0

    subtrees = UnionFind() 
    edges = [(G[p1,p2],p1,p2) for p1 in nodes for p2 in nodes ]
    edges.sort()
    hDistance = 0
    for W,u,v in edges:
        if subtrees[u] != subtrees[v]:
            hDistance += W
            subtrees.union(u,v)
    return hDistance
Beispiel #13
0
def get_connected_components(img):
    components = cc.get_connected_components(img)
    components = scale_components(components)
    connected = UnionFind()
    for comp1 in components:
        for comp2 in components:
            if overlaps(comp1, comp2):
                connected.union((comp1[0].start, comp1[0].stop, comp1[1].start,
                                 comp1[1].stop),
                                (comp2[0].start, comp2[0].stop, comp2[1].start,
                                 comp2[1].stop))

    connected_sets = {}
    for child, parent in connected.parents.iteritems():
        if parent not in connected_sets:
            connected_sets[parent] = []
        connected_sets[parent].append(child)

    connected_comps = []

    for a, comps in connected_sets.iteritems():
        min_y = min(comps, key=lambda item: item[0])[0]
        max_y = max(comps, key=lambda item: item[1])[1]
        min_x = min(comps, key=lambda item: item[2])[2]
        max_x = max(comps, key=lambda item: item[3])[3]
        connected_comps.append((slice(min_y, max_y), slice(min_x, max_x)))
    return connected_comps
Beispiel #14
0
 def __getTree(self):
     # Sort edges by decreasing pheromone levels
     self.edgeInfos.sort(key=geteiPheromoneLevel, reverse=True)
     start = 0
     # Current edges that will be inspected
     C = []
     # Data structure for Kruskal's algorithm
     subtrees = UnionFind() 
     solution = []
     degrees = defaultdict(int) # Map of degrees for each vertice
     
     # While we don't have n-1 edges in our solution
     while len(solution) != self.n - 1:
         # Pick the the next nCanditates edges
         C = self.edgeInfos[start : start + self.nCandiates]
         
         # Sort the edge selection by increasing cost
         C.sort(key=geteiCost)
         start += self.nCandiates
         
         for ei in C:
             u, v = ei.u, ei.v
             # Test if edge can be added to the current solution
             if subtrees[u] != subtrees[v] and \
                degrees[u] < self.d and degrees[v] < self.d:  # Check constraint
                 solution.append(ei)
                 # Increment degrees of vertices of the added edge
                 degrees[u] += 1
                 degrees[v] += 1
                 # Update subtrees
                 subtrees.union(u, v)
     return solution
def kcluster(nodeset, edgeset, num_clusters, k):#WRONG
    """
        Standard Algorithm
    """
    #TODO: Validate Edgecase when k> len(nodeset) or len(edgeset)
    # Sort edgeset by Cost
    sorted_edges = sorted(edgeset, key=lambda x: x[2])
    # Add each node to nodeset into UnionFind S
    uf = UnionFind()
    for node in nodeset:
        uf[node]

    # For each edge (u,v) in edgeset
    for edge in sorted_edges:
        #print 'Num Clusters {0}'.format(uf.size())
        head, tail, wt = edge
        if num_clusters == k:
            print "STOP {0}".format(edge)
            max_crossing = wt
            return (uf , wt)

        if uf[head] != uf[tail]:
            uf.union(head, tail)
            num_clusters -=1


  
    return (uf , wt)
Beispiel #16
0
def MinimumSpanningTree(graph, weights):
    """
    Return the minimum spanning tree of an undirected graph G.
    G should be represented in such a way that iter(G) lists its
    vertices, iter(G[u]) lists the neighbors of u, G[u][v] gives the
    length of edge u,v, and G[u][v] should always equal G[v][u].
    The tree is returned as a list of edges.
    """
    if not isinstance(graph, UndirectedGraph):
        raise ValueError("Provided graph is not an UndirectedGraph.")
    for vertex in range(graph.n_vertices):
        for child in graph.adjacency_list[vertex]:
            if weights[vertex, child] != weights[child, vertex]:
                raise ValueError("Assymetric weights provided.")

    # Kruskal's algorithm: sort edges by weight, and add them one at a time.
    # We use Kruskal's algorithm, first because it is very simple to
    # implement once UnionFind exists, and second, because the only slow
    # part (the sort) is sped up by being built in to Python.
    subtrees = UnionFind()
    tree = []
    for W, u, v in sorted((weights[u][v], u, v) for u in range(graph.n_vertices)
                          for v in graph.adjacency_list[u]):
        if subtrees[u] != subtrees[v]:
            tree.append((u, v))
            subtrees.union(u, v)
    return tree
def MinimumSpanningTree(G):
    """
    Return the minimum spanning tree of an undirected graph G.
    G should be represented in such a way that iter(G) lists its
    vertices, iter(G[u]) lists the neighbors of u, G[u][v] gives the
    length of edge u,v, and G[u][v] should always equal G[v][u].
    The tree is returned as a list of edges.
    """
    if not isUndirected(G):
        raise ValueError("MinimumSpanningTree: input is not undirected")
    for u in G:
        for v in G[u]:
            if G[u][v] != G[v][u]:
                raise ValueError("MinimumSpanningTree: asymmetric weights")

    # Kruskal's algorithm: sort edges by weight, and add them one at a time.
    # We use Kruskal's algorithm, first because it is very simple to
    # implement once UnionFind exists, and second, because the only slow
    # part (the sort) is sped up by being built in to Python.
    subtrees = UnionFind()
    tree = []
    for W, u, v in sorted((G[u][v], u, v) for u in G for v in G[u]):
        if subtrees[u] != subtrees[v]:
            tree.append((u, v))
            subtrees.union(u, v)
    return tree
Beispiel #18
0
def approx(nodes, tracepoint_pipe: Pipe, solution_pipe: Pipe):

    start_time = time.process_time()  # Get start time in seconds

    n = len(nodes)  # Cache the number of nodes

    # Construct a list of edges sorted by cost
    edge_list = []
    for i in range(n):
        for j in range(i + 1, n):
            # Construct an edge
            e = Edge(nodes[i], nodes[j])
            bisect.insort(edge_list, e)

    m = len(edge_list)  # Cache the number of edges

    union_find = UnionFind()
    for i in range(n):
        set = UnionFindSet(nodes[i])
        union_find.add_set(set)

    solution = mst_approx(union_find, nodes, edge_list)
    solution_pipe.send(solution)
    tracepoint_pipe.send(
        Tracepoint(time.process_time() - start_time, solution.quality))

    exit(0)  # Exit the process
def connectedComponentOutsidePermittedRegionBlacken(img, vstart, vend):
  labels = UnionFind()
  # pass 1
  labeled = set()
  for currentPoint in iterImg(img):
    y,x = currentPoint
    if sum(img[y,x]) <= 100: # black
      continue
    labeled.add(currentPoint)
    neighbors = getSurrounding1(img, y, x)
    # if all 4 neighbors are black or unlabeled (ie, 0 labeled white neighbors), assign new label
    # if only 1 neighbor is white, assign its label to current point
    # if more than 1 of the neighbors are white, assign one of their labels to the current point, and note equivalence
    labeled_white_neighbors = [neighbor for neighbor in neighbors if sum(img[neighbor]) > 100 and neighbor in labeled]
    if len(labeled_white_neighbors) == 0: # assign new label
      z = labels[currentPoint]
    else:
      for neighbor in labeled_white_neighbors:
        labels.union(neighbor, currentPoint)
  # now blacklist all sets st they have a child that is in the forbidden region
  blacklist = set()
  for currentPoint in labeled:
    y,x = currentPoint
    if y < vstart or y > vend:
      blacklist.add(labels[currentPoint])
  # pass 2 - blacken blacklisted components
  for currentPoint in labeled:
    y,x = currentPoint
    curset = labels[currentPoint]
    if curset in blacklist:
      img[y,x] = (0,0,0)
Beispiel #20
0
class KruskalMST:
    def __init__(self, graph):
        self.graph = graph
        self.mst = []
        self.minh = MinHeap()
        self.Uf = UnionFind(graph.V())
        #将所有的边推入到最小堆中,由于是无向图,剔除掉重复的边,复杂度O(Elog(E))
        for i in range(graph.V()):
            it = graph.adj(i)  #由于是无向图,所以会有重复的边,用E.v() < E.w()来剔除另一半重复的边
            for E in it:
                if E.v() < E.w():
                    self.minh.add(E)
        #当最小堆为空,或是所有的点都已经遍历完时,结束
        #所有的边取出来且判断一下其是否形成环,复杂度,O(Elog(V))
        while not self.minh.isEmpty() and len(self.mst) < self.graph.V():
            minE = self.minh.extractMin()
            if not self.Uf.isConnected(minE.v(), minE.w()):
                self.mst.append(minE)
                self.Uf.union(minE.v(), minE.w())

    def mstEdges(self):
        return self.mst

    def mstWeight(self):
        mstw = []
        for E in self.mst:
            mstw.append(E.wt())
        return mstw

    # 返回最小生成树的权值
    def minWeight(self):
        mstw = self.mstWeight()
        return sum(mstw)
 def test_getitem_returns_proper_root(self):
     union_find = UnionFind()
     union_find.union('parent', 'first_child')
     union_find.union('first_child', 'last_child')
     self.assertEqual(union_find['parent'], 'parent')
     self.assertEqual(union_find['first_child'], 'parent')
     self.assertEqual(union_find['last_child'], 'parent')
def read_nodes(filename):
    clusters = UnionFind()
    all_nodes = []
    with open(filename) as inputfile:
        next(inputfile)
        for line in inputfile:
            clusters.make_set(int(line.rstrip().replace(' ', ''), 2))
            all_nodes.append(int(line.rstrip().replace(' ', ''), 2))
    return clusters, all_nodes
Beispiel #23
0
 def __init__(self, width, threshold, k):
     self.width = width
     self.unionfind = UnionFind()
     self.signer = MinHashSignature(width)
     self.hasher = LSH(width, threshold)
     self.hashmaps = [
         defaultdict(list) for _ in range(self.hasher.get_n_bands())
     ]
     self.k = k
Beispiel #24
0
 def __init__(self, file_list, file_path, error_path, id_list_file, save_path):
     self._id_list = np.array(pd.read_csv(id_list_file)['p_id'])
     self._file_list = file_list
     self._uf_set = UnionFind(self._id_list)
     self._file_path = file_path
     self._error_path = error_path
     self._error_id_list = []
     self._save_path = save_path
     self._break_point = -1
Beispiel #25
0
    def load_break_point(self, load_data, break_point):
        new_uf = UnionFind([key for key in data])

        for key in load_data:
            for cor_id in load_data[key]:
                new_uf.union(key, cor_id)

        self._uf_set = new_uf
        self._break_point = break_point
        self._error_id_list = list(pd.read_csv(self._error_path + "/error_id_list.csv")['p_id'])
Beispiel #26
0
    def _cargar_estructuras(self):
        self.uf_fuegos = UnionFind(len(self.focos))
        for foco in self.focos:
            if foco.fecha not in self.dias:
                self.dias[foco.fecha] = list()
            #agrupo por dias
            self.dias[foco.fecha].append(foco)

        self.dias = self.dias.values()
        self.dias = sorted(self.dias, key=lambda dia: dia[0].fecha)
Beispiel #27
0
def kruskal(edges, num_vertex):
    uft = UnionFind(num_vertex)
    cost_sum = 0    # 最小全域木のコストの総和

    edges = sorted(edges, key = lambda x: x[2])
    for e in edges:
        if not uft.find(e[0], e[1]):
            uft.union(e[0], e[1])
            cost_sum += e[2]
    return cost_sum
def Kruskal(Adj):
    subtree = UnionFind()
    tree = []
    for e, u, v in sorted((Adj[u][v], u, v) for u in Adj for v in Adj[u]):
        for u in Adj:
            for v in Adj[u]:
                if subtree[u] != subtree[v]:
                    tree.append((u, v))
                    subtree.union(u, v)
    print tree
Beispiel #29
0
def minimumSpanningTree(edges):
    subtrees = UnionFind()
    tree = []
    for e in edges:
        if subtrees[e.v1] != subtrees[e.v2]:
            tree.append(e)
            subtrees.union(e.v1,e.v2)
            e.v1.degree += 1
            e.v2.degree += 1
    return tree
def max_spacing_k_clustering(G, V, k):
    '''
    Apply a variant of Kruskal's MST algorithm to max-spacing k-clustering problems.
    Return the maximum spacing of k-clustering.
    
    G is a list which represents a graph. 
    Each value of G, G[i], is a tuple (u,v,edge_cost) which represents two vertices of an edge and the cost of that edge.
    V is a list of vertices.
    k is the number of clusters.
    '''
    # use Union-Find data structure to represent clusters
    unionfind=UnionFind()
    
    heap=[] # edges
    for u,v,cost in G:
        heappush(heap,(cost,u,v))
      
    n=len(V) # number of vertices
    i=0
    while i<n-k: # An MST has n-1 edges. Stops early by k-1 steps to produce a k-clustering.
        cost,u,v=heappop(heap) # pop the edge with least cost
             
        # check cycle. No cycles if either vertex has not be added to any cluster or they belong to different clusters.
        if unionfind.find(u) is None or unionfind.find(v) is None or unionfind.find(u)!=unionfind.find(v):
            # add the edge.
            unionfind.union(u,v)
            i+=1
            
#     unionfind.getNumGroups()
    
    # in case that vertices of next edges has been added to the same cluster.
    while True:
        cost,u,v=heappop(heap)
        if unionfind.find(u) is None or unionfind.find(v) is None or unionfind.find(u)!=unionfind.find(v):
            return cost
Beispiel #31
0
def Kruskal(SetOfPoints, type):
    """Kruskal's Algorithm
	Sorts edges by weight, and adds them one at a time to the tree while avoiding cycles
	Takes any set of Point instances and converts to a dictionary via edge crawling 
	Takes the dictionary and iterates through each level to discover neighbors and weights
	Takes list of point index pairs and converts to list of Lines then returns
	"""

    for i in xrange(0, len(SetOfPoints)):
        SetOfPoints[i].reset()
    for i in xrange(0, len(SetOfPoints)):
        for j in xrange(i, len(SetOfPoints)):
            if i != j:
                if type == "R":
                    dist = (abs(SetOfPoints[i].x - SetOfPoints[j].x) +
                            abs(SetOfPoints[i].y - SetOfPoints[j].y))
                elif type == "G":
                    dist = math.sqrt(
                        pow((SetOfPoints[i].x - SetOfPoints[j].x), 2) +
                        pow((SetOfPoints[i].y - SetOfPoints[j].y), 2))
                else:
                    "All of the Errors!"
                line = Line(SetOfPoints[i], SetOfPoints[j], dist)
                SetOfPoints[i].update(line)
                SetOfPoints[j].update(line)
            else:
                dist = 100000
                line = Line(SetOfPoints[i], SetOfPoints[j], dist)
                SetOfPoints[i].update(line)

    G = {}
    for i in xrange(0, len(SetOfPoints)):
        off = 0
        subset = {}
        for j in xrange(0, len(SetOfPoints[i].edges)):
            subset[j] = SetOfPoints[i].edges[j].w
        G[i] = subset

    subtrees = UnionFind()
    tree = []
    for W, u, v in sorted((G[u][v], u, v) for u in G for v in G[u]):
        if subtrees[u] != subtrees[v]:
            tree.append([u, v])
            subtrees.union(u, v)

    MST = []
    for i in xrange(0, len(tree)):
        point1 = SetOfPoints[tree[i][0]]
        point2 = SetOfPoints[tree[i][1]]
        for j in xrange(0, len(point1.edges)):
            if point2 == point1.edges[j].getOther(point1).get():
                point1.MSTupdate(point1.edges[j])
                point2.MSTupdate(point1.edges[j])
                MST.append(point1.edges[j])
    return MST
def GetMinimumSpanningTree(graph):
    subtrees = UnionFind()
    spanningTree = WeightedGraph()
    sorted_weighted_edges_list = sorted([(u, v, graph[u][v]) for u in graph
                                         for v in graph[u]],
                                        key=lambda item: item[-1])
    for u, v, w in sorted_weighted_edges_list:
        if subtrees[u] != subtrees[v]:
            spanningTree.AddEdge(u, v, w)
            subtrees.union(u, v)
    return spanningTree
Beispiel #33
0
    def __init__(self, data):
        (nodes, self.bits) = map(int, data.pop(0).split())
        self.uf = UnionFind()
        for n in range(nodes):
            self.uf.makeSet(n)
        # END for

        self.hammingData = defaultdict(list)
        for n in range(nodes):
            s = data[n].replace(' ', '')
            self.hammingData[s].append(n)
    def testUnionNotIntegers(self):
        elements = ["bye", "a", "80", "cat"]
        uf = UnionFind(elements)

        uf.union("a", "80")
        uf.union("80", "cat")

        self.assertFalse(uf.find("bye") in set(["80", "a", "cat"]))
        self.assertTrue(uf.find("a") in set(["80", "a", "cat"]))
        self.assertTrue(uf.find("cat") in set(["80", "a", "cat"]))
        self.assertTrue(uf.find("80") in set(["80", "a", "cat"]))
def GetMinimumSpanningTree(graph):
    subtrees = UnionFind()
    spanningTree = WeightedGraph()
    sorted_weighted_edges_list = sorted(
        [(u, v, graph[u][v]) for u in graph for v in graph[u]],
        key=lambda item: item[-1]
    )
    for u, v, w in sorted_weighted_edges_list:
        if subtrees[u] != subtrees[v]:
            spanningTree.AddEdge(u, v, w)
            subtrees.union(u, v)
    return spanningTree
Beispiel #36
0
	def kruskalsMST(self):
		edges = self.sortedGraph
		uf = UnionFind()
		T = []
		total_cost = 0
		for cost,source,target in edges:
			s1,s2 = uf[source],uf[target]
			if s1 != s2 :
				uf.union(s1,s2)
				T.append((source,target))
				total_cost += cost
		return total_cost
Beispiel #37
0
def MinimumSpanningTree(G):
    for u in G:
        for v in G[u]:
            if G[u][v] != G[v][u]:
                raise ValueError("MinimumSpanningTree: asymmetric weights")

    subtrees = UnionFind()
    tree = []
    for W,u,v in sorted((G[u][v],u,v) for u in G for v in G[u]):
        if subtrees[u] != subtrees[v]:
            tree.append((u,v))
            subtrees.union(u,v)
    return tree
def importGraph(filename = 'clustering2.txt'):
    """Imports pairs of endpoints into an adjancey list graph representation.
    Keep track of both edges and vertices."""
    f = open(filename)
    (totalnodes, bits) = [int(x) for x in f.readline().split()]
    nodecount = 0
    nodes = {}
    for line in f:
        nodes[nodecount] = [int(x) for x in line.split()]
        nodecount += 1
    f.close()

    count = 0
    buckets = {}
    # prep buckets
    for i in range(0, bits - 1):
        for j in range(i + 1, bits):
            buckets[(i, j)] = {}
            # print i, j
            count += 1
    print count

    count = 0
    for nkey, nval in nodes.items():
        count += 1
        if count % 1000 == 0:
            print count
        for i in range(0, bits - 1):
            for j in range(i + 1, bits):
                nvalminustwo = tuple(nval[0:i] + nval[i+ 1:j] + nval[j+1: bits])

                if not buckets[(i, j)].has_key(nvalminustwo):
                    buckets[(i, j)][nvalminustwo] = [nkey]
                else:
                    buckets[(i, j)][nvalminustwo].append(nkey)

    uf = UnionFind()

    for n in xrange(len(nodes)):
        uf[n]

    count = 0
    for key in buckets.keys():
        for valkey in buckets[key]:

            count += 1
            if count % 1000000 == 0:
                print count
            uf.union(*buckets[key][valkey])

    return uf
class Kruskal:
    def __init__(self, data):
        nodes = int(data[0].split()[0])
        self.ufSet = UnionFind()
        for n in range(nodes):
            self.ufSet.makeSet(n)
        # END for

        self.edges = []
        for k in data[1:]:
            row = map(int, k.strip().split())
            self.edges.append((row[0] - 1, row[1] - 1, row[2]))
        # END for

        self.edges.sort(key=itemgetter(2))

    # END __init__

    def mstKruskal(self):
        mst = []
        l = 0
        for edge in self.edges:
            s1 = self.ufSet.find(edge[0])
            s2 = self.ufSet.find(edge[1])
            if s1 == s2:
                continue
            # END if

            self.ufSet.union(edge[0], edge[1])
            mst.append(edge)
            l += edge[2]
        # END for

        self.mst = mst
        return l

    # END mstKruskal

    def clusterKruskal(self, k):
        print "Running Clustering, k={0}".format(k)
        done = False
        for edge in self.edges:
            s1 = self.ufSet.find(edge[0])
            s2 = self.ufSet.find(edge[1])
            if s1 == s2:
                continue
            # END if
            if not done:
                self.ufSet.union(edge[0], edge[1])
            else:
                print "Smallest unallocated edge: {0}".format(edge)
                return edge[2]
            # END if

            if self.ufSet.countGroups() == k:
                done = True
def k_means_clustering(k, num_nodes, edges):

    print edges
    U = UnionFind(num_nodes)
    X = []

    cluster_count = num_nodes
    for everyedge in edges:
        p = everyedge[1] - 1
        q = everyedge[2] - 1

        if cluster_count == k:
            break

        if U.root(p) != U.root(q):
            X.append(everyedge)
            U.union(p, q)
            cluster_count = cluster_count - 1

    print U
    i = 0
    k_min_spacing = float('inf')
    while (i < len(edges)):
        w, p, q = edges[i]
        if U.root(p - 1) != U.root(q - 1):
            print p, q, w
            k_min_spacing = w if w < k_min_spacing else k_min_spacing
        i = i + 1

    return k_min_spacing
    def validTreeUF2(self, n, edges):
        """
        :type n: int
        :type edges: List[List[int]]
        :rtype: bool
        """
        # if len(edges) != n - 1:
        #     return False

        uf = UnionFind(n)
        for i, j in edges:
            uf.union(i, j)
        print(uf.parent)
        return uf.group == 1
    def __init__(self, data):
        nodes = int(data[0].split()[0])
        self.ufSet = UnionFind()
        for n in range(nodes):
            self.ufSet.makeSet(n)
        # END for

        self.edges = []
        for k in data[1:]:
            row = map(int, k.strip().split())
            self.edges.append((row[0] - 1, row[1] - 1, row[2]))
        # END for

        self.edges.sort(key=itemgetter(2))
def Kruskal(SetOfPoints, type):
    for i in xrange(0, len(SetOfPoints)):
        SetOfPoints[i].reset()
    for i in xrange(0, len(SetOfPoints)):
        for j in xrange(i, len(SetOfPoints)):
            if i != j:
                if type == "R":
                    dist = (abs(SetOfPoints[i].x - SetOfPoints[j].x) +
                            abs(SetOfPoints[i].y - SetOfPoints[j].y))
                elif type == "G":
                    dist = math.sqrt(
                        pow((SetOfPoints[i].x - SetOfPoints[j].x), 2) +
                        pow((SetOfPoints[i].y - SetOfPoints[j].y), 2))
                else:
                    "All of the Errors!"
                line = Line(SetOfPoints[i], SetOfPoints[j], dist)
                SetOfPoints[i].update(line)
                SetOfPoints[j].update(line)
            else:
                dist = 100000
                line = Line(SetOfPoints[i], SetOfPoints[j], dist)
                SetOfPoints[i].update(line)

    G = {}
    for i in xrange(0, len(SetOfPoints)):
        off = 0
        subset = {}
        for j in xrange(0, len(SetOfPoints[i].edges)):
            subset[j] = SetOfPoints[i].edges[j].w
        G[i] = subset

    subtrees = UnionFind()
    tree = []
    for W, u, v in sorted((G[u][v], u, v) for u in G for v in G[u]):
        if subtrees[u] != subtrees[v]:
            tree.append([u, v])
            subtrees.union(u, v)

    MST = []
    for i in xrange(0, len(tree)):
        point1 = SetOfPoints[tree[i][0]]
        point2 = SetOfPoints[tree[i][1]]
        for j in xrange(0, len(point1.edges)):
            if point2 == point1.edges[j].getOther(point1).get():
                point1.MSTupdate(point1.edges[j])
                point2.MSTupdate(point1.edges[j])
                MST.append(point1.edges[j])
    return MST
Beispiel #44
0
def init(arguments):
    # taille			# contient la taille du plateau
    # plateau			# plateau de jeu où l'on stocke le joueur (0, 1 ou 2) associé à chaque cellule
    # gs				# socket connectée à l'autre joueur
    # monTour			# booléen True ssi c'est à mon tour de jouer
    # numJoueur			# contient mon numéro (1 ou 2) de joueur
    # uf				# structure Union-Find pour déterminer les cellules connectées
    # couleurs			# contient les couleurs utilisées sur le plateau de l'interface graphique

    hv.couleurs = ['white', 'red', 'blue']

    if arguments["ip"] != None:
        # on est le client
        initClient(arguments)
    else:
        # on est le serveur
        initServeur(arguments)

    # initialisation du plateau et de la structure union-find
    # le plateau est un dictionnaire; il pourrait être un tableau
    hv.plateau = {}
    for i in range(hv.taille):
        for j in range(hv.taille):
            hv.plateau[i, j] = 0

    hv.uf = UnionFind()
    hv.uf.union((1, "haut"), *[(-1, i) for i in range(hv.taille)])
    hv.uf.union((1, "bas"), *[(hv.taille, i) for i in range(hv.taille)])
    hv.uf.union((2, "haut"), *[(i, -1) for i in range(hv.taille)])
    hv.uf.union((2, "bas"), *[(i, hv.taille) for i in range(hv.taille)])

    # queue pour gérer les messages de fin de connexion entre thread
    Aurevoir.Messages = Queue()

    print("--- Initialisation terminée. La partie commence.")
Beispiel #45
0
    def __init__(self,parent,pairs):
        """Set up to find LCAs of pairs in tree defined by parent.
        LCA of any given pair x,y can then be found by self[x][y].
        However unlike the online LCA structure we can not find LCAs
        of pairs that are not supplied to us at startup time.
        """

        # set up dictionary where answers get stored
        dict.__init__(self)
        for u,v in pairs:
            self.setdefault(u,{})[v] = self.setdefault(v,{})[u] = None

        # set up data structure for finding node ancestor on search path
        # self.descendants forms a collection of disjoint sets,
        #    one set for the descendants of each search path node.
        # self.ancestors maps disjoint set ids to the ancestors themselves.
        self.descendants = UnionFind()
        self.ancestors = {}

        # invert the parent relationship so we can traverse the tree
        self.children = {}
        for x,px in parent.iteritems():
            self.children.setdefault(px,[]).append(x)
        root = [x for x in self.children if x not in parent]
        if len(root) != 1:
            raise ValueError("LCA input is not a tree")

        # initiate depth first traversal
        self.visited = Set()
        self.traverse(root[0])
Beispiel #46
0
    def run(self):
        L = self.L
        R = self.R
        percolates = False

        union = UF(L * L + 2)
        # bottom
        for i in range(1, L + 1):
            union.union(i, 0)
        # top
        for i in range(L * L - L + 1, L * L + 1):
            union.union(i, L * L + 1)

        particles = set()
        edges     = set()

        while len(particles) != self.N:
            if percolates: break
            p = random.randrange(L, L * L - L)
            particles.add(p)
            current_vertice = self.g.vertex(p)
            self.vertices_color[current_vertice] = [0, 1, 0, 1]
            x, y = self._get_pos(p)
            for i in range(max(0, x - R), min(L, x + R + 1)):
                if percolates: break
                for j in range(max(0, y - R), min(L, y + R + 1)):
                    if (i, j) == (x, y): continue
                    if self._sqrdist((i, j), (x, y)) > R * R: continue
                    if i <= x: 
                        from_, to_ = i * L + j, p
                    else: 
                        from_, to_ = p, i * L + j
                    if i * L + j in particles or i == 0 or i == L - 1:
                        union.union(from_ + 1, to_ + 1)
                        edges.add((from_, to_))
                    if union.connected(L * L + 1, 0): 
                        percolates = True


        for edge in edges:
            if union.connected(0, edge[0] + 1):
                current_edge = self.g.add_edge(self.vertices[edge[0]], self.vertices[edge[1]])
                self.pen[current_edge] = 3
                if percolates:
                    self.edge_color[current_edge] = [0, 0, 1, 1]
                else:
                    self.edge_color[current_edge] = [1, 0, 0, 1]

        if percolates:
            self.tests.append(len(particles))

        return percolates
def kcluster2(nodeset,edgeset,num_clusters,k): #CORRECT
    sorted_edges = sorted(edgeset, key=lambda x: x[2])
    # Add each node to nodeset into UnionFind S
    uf = UnionFind()
    for node in nodeset:
        uf[node]
    while num_clusters > k:
        head, tail, wt = sorted_edges.pop(0)
        while uf[head] == uf[tail]:
            head, tail, wt = sorted_edges.pop(0)
        uf.union(head, tail)
        num_clusters-=1
    
    head, tail, wt = sorted_edges.pop(0)
    while uf[head] == uf[tail]:
       head, tail, wt = sorted_edges.pop(0)
    return head, tail, wt
Beispiel #48
0
class OfflineLCA(defaultdict):
    """Find LCAs of all pairs in a given sequence, using Union-Find."""

    def __init__(self,parent,pairs):
        """Set up to find LCAs of pairs in tree defined by parent.
        LCA of any given pair x,y can then be found by self[x][y].
        However unlike the online LCA structure we can not find LCAs
        of pairs that are not supplied to us at startup time.
        """

        # set up dictionary where answers get stored
        defaultdict.__init__(self,dict)
        for u,v in pairs:
            self[u][v] = self[v][u] = None

        # set up data structure for finding node ancestor on search path
        # self.descendants forms a collection of disjoint sets,
        #    one set for the descendants of each search path node.
        # self.ancestors maps disjoint set ids to the ancestors themselves.
        self.descendants = UnionFind()
        self.ancestors = {}

        # invert the parent relationship so we can traverse the tree
        self.children = defaultdict(list)
        for x,px in parent.items():
            self.children[px].append(x)
        root = [x for x in self.children if x not in parent]
        if len(root) != 1:
            raise ValueError("LCA input is not a tree")

        # initiate depth first traversal
        self.visited = set()
        self.traverse(root[0])

    def traverse(self,node):
        """Perform depth first traversal of tree."""
        self.ancestors[self.descendants[node]] = node
        for child in self.children[node]:
            self.traverse(child)
            self.descendants.union(child,node)
            self.ancestors[self.descendants[node]] = node
        self.visited.add(node)
        for query in self[node]:
            if query in self.visited:
                lca = self.ancestors[self.descendants[query]]
                self[node][query] = self[query][node] = lca
Beispiel #49
0
class hamClusters :
	def __init__(self,file):
		self.file = file
		self.hamm=[0]*300
		self.hamcode()
		self.points = [0]*pow(2,24)
		self.clusters = 0
		self.index = {}
		self.uf = UnionFind()
		self.process_data()

	def spacing(self):
		for node in  self.index.keys():
			self.cluster_neighbors(node)
		return self.clusters

	def process_data(self):
		with open(self.file) as f:
		    next(f)
		    cluster=1
		    for line in f:
			curindex=int(line.replace(' ',''), base = 2)
			self.points[curindex] = cluster
			self.index[curindex] = True
			cluster += 1
		self.clusters = len(self.index)
		print 'size=', self.clusters, len(self.points)

	def hamcode(self):
		#computing simple numbers
		k=0
		for i in range(24):
		    for j in range(i,24):
			mask=1 << i
			mask2 = 1 << j
			self.hamm[k]=mask|mask2
			k=k+1
	
	def cluster_neighbors(self,node):
	    	for i in self.hamm:
			if self.points[node^i] !=0:
				s1 = self.uf[node]
				s2 = self.uf[node^i]
				if s1 != s2:
					self.uf.union(s1,s2)
					self.clusters -= 1
Beispiel #50
0
	def k_clustering(self):
		edges = self.sortedGraph
		uf = UnionFind()
		size = 500
		cluster_size = 4
		spacing = 0

		for spacing,source,target in edges:
			s1,s2 = uf[source],uf[target]
			# enough clusters, return the spacing
			if size <= cluster_size:
				if s1 != s2:
					return spacing
		# if in different clsuters, join them reducing one cluster
			if s1 != s2 :
				uf.union(s1,s2)
				size -= 1
		return spacing
Beispiel #51
0
	def __init__(self,file):
		self.file = file
		self.hamm=[0]*300
		self.hamcode()
		self.points = [0]*pow(2,24)
		self.clusters = 0
		self.index = {}
		self.uf = UnionFind()
		self.process_data()
class UFGraphBasedSegment:

  def __init__(self, size, tau_k, root_dict):
    self.uf = UnionFind(size, root_dict)
    self.tau_k = tau_k

  '''
  Merge two components.
  @param id1 : component id to merge
  @param id2 : component id to merge
  @param edge_value : difference value of intertested edge
  @return bool : TRUE if merging two components, else FALSE
  '''
  def merge(self, id1, id2, edge_value):
    root_node1 = self.uf.get_root(id1)
    root_node2 = self.uf.get_root(id2)
    if edge_value < self.mint(root_node1, root_node2):
      self.uf.union(id1=id1, id2=id2, edge_value=edge_value)

  '''
  Calculate the minimum internal difference between two components.
  @param id1 : One of two components to calculate minimum internal difference of boundary
  @param id2 : One of two components to calculate minimum internal difference of boundary
  @param mcl : Merged Component List
  @return float : minimum internal difference between two components
  '''
  def mint(self, r1, r2):
    return min(r1.get_min_dif()+self.tau(r1), r2.get_min_dif()+self.tau(r2))

  '''
  Calculate threashold based on the size of the component.
  @param mc : merged component to calculate the threashold
  @return float : threashold based on the size of the component
  '''
  def tau(self, root):
    return float(self.tau_k / root.get_size())

  '''
  Get union find.
  @return UnionFind : union find tree
  '''
  def get_union_find(self):
    return self.uf
Beispiel #53
0
	def __init__(self, N):
		self.uf = UnionFind()
		[self.uf[(n,m)] for n in range(N) for m in range(N)]
		self.grid = {(n,m):0 for n in range(N) for m in range(N)}
		self.N = N

		#setup virtual cells on top and bottom
		self.vtop = (-1,-1)
		self.grid[self.vtop] = 1
		self.vbot = (self.N,self.N)
		self.grid[self.vbot] = 1
Beispiel #54
0
def kruskalMST(myGraph):
	T = []												#T is defined to be the empty set

	#2. For each vertex v of G, make the empty set out of v;
	edges = []
	for v1 in range(0, len(myGraph)):
		for v2 in range(v1+1, len(myGraph)):
			newEdge = [v1, v2, distanceC2C(myGraph[v1], myGraph[v2])]
			edges.append(newEdge)

	edges = sorted(edges, key=getKey)					#Sort edges in ascending order

	subtrees = UnionFind()

	for edge in edges:									#For each edge from sorted list
		if (subtrees[edge[0]] != subtrees[edge[1]]): 	#If u and v belong to different sets
			T.append(edge) 								#Add edge to T
			subtrees.union(edge[0], edge[1])			#Get u and v in one single set

	return T
def MinimumSpanningTree(G):
    """
    Return the minimum spanning tree of an undirected graph G.
    G should be represented in such a way that G[u][v] gives the
    length of edge u,v, and G[u][v] should always equal G[v][u].
    The tree is returned as a list of edges.
    """

    # Kruskal's algorithm: sort edges by weight, and add them one at a time.
    # We use Kruskal's algorithm, first because it is very simple to
    # implement once UnionFind exists, and second, because the only slow
    # part (the sort) is sped up by being built in to Python.
    subtrees = UnionFind()
    tree = []
    edges = [(G[u][v],u,v) for u in G for v in G[u]]
    edges.sort()
    for W,u,v in edges:
        if subtrees[u] != subtrees[v]:
            tree.append((u,v))
            subtrees.union(u,v)
    return tree
def krusal(nodeset, edgeset):
    # Sort edgeset by Cost
    edgelist=sorted(edgeset, key=lambda x:x[2])

    # Add each node to nodeset into UnionFind S
    uf = UnionFind()
    for node in nodeset:
        uf[node]

    # Initialize T to empty set ([])
    mst = set([])

    # For each edge (u,v) in edgeset
    for edge in edgelist:
        head,tail,_ = edge
        # If u or v creates a cycle in T then continue (e.g. is S[u] == S[v])
        if uf[head] != uf[tail]: # else Add (u,v) to T AND S.union(u, v).
            mst.add(edge)
            uf.union(head,tail)

    return mst
def connectedComponentLabel(img):
  labels = UnionFind()
  labeled = set()
  # pass 1
  for surroundingPoints in iterImgSurrounding1(img):
    currentPoint = surroundingPoints[0]
    y,x = currentPoint
    if sum(img[y,x]) <= 100: # black
      continue
    labeled.add(currentPoint)
    neighbors = surroundingPoints[1:]
    # if all 4 neighbors are black or unlabeled (ie, 0 labeled white neighbors), assign new label
    # if only 1 neighbor is white, assign its label to current point
    # if more than 1 of the neighbors are white, assign one of their labels to the current point, and note equivalence
    labeled_white_neighbors = [neighbor for neighbor in neighbors if sum(img[neighbor]) > 100 and neighbor in labeled]
    if len(labeled_white_neighbors) == 0: # assign new label
      z = labels[currentPoint]
    else:
      label = labels[labeled_white_neighbors[0]]
      labels.union(label, currentPoint)
      for neighbor in labeled_white_neighbors[1:]:
        labels.union(label, neighbor)
  # pass 2
  set_num = 1
  set_to_num = {}
  outimg = CreateImage((img.width, img.height), 8, 3)
  for currentPoint in iterImg(img):
    y,x = currentPoint
    if sum(img[y,x]) <= 100: # black
      outimg[y,x] = (0,0,0)
      continue
    curset = labels[currentPoint]
    #print curset
    if curset not in set_to_num:
      set_to_num[curset] = encodeNumAsColor(set_num)
      set_num += 1
      #print set_num
    outimg[y,x] = set_to_num[curset]
  return outimg
Beispiel #58
0
def kerger_UF(Edges,n):
	cut = 0
	uf = UnionFind()
	random.shuffle(Edges)
	i = 0;
	# Populate the clusters of UF till there are 2 nodes left.
	while n > 2:
		e1,e2 = Edges[i]
		i += 1
		s1 = uf[e1]
		s2 = uf[e2]
		if s1 != s2:
			uf.union(s1,s2)
			n -= 1

	# Check for edges that cross the clusters, which are mincut edges
	for e1,e2 in Edges:
		s1 = uf[e1]
		s2 = uf[e2]
		if s1 != s2:
			cut += 1
	return cut
def MinimumSpanningTree(prob,InputWords):
    """
    Return the minimum spanning tree of an undirected graph G.
    G should be represented in such a way that G[u][v] gives the
    length of edge u,v, and G[u][v] should always equal G[v][u].
    The tree is returned as a list of edges.
    """
    
   # Kruskal's algorithm: sort edges by weight, and add them one at a time.
    # We use Kruskal's algorithm, first because it is very simple to
    # implement once UnionFind exists, and second, because the only slow
    # part (the sort) is sped up by being built in to Python.
    #print "MST"
    subtrees = UnionFind()
    dictionary = {}
    tree = []
    edges = [(prob[InputWords.index(u)][InputWords.index(v)],u,v) for u in InputWords for v in InputWords]
    edges.sort()
    edges.reverse()
    for W,u,v in edges:
        if subtrees[u] != subtrees[v]:
            if u not in dictionary:
                tNode = TreeNode.TreeNode(u)
                dictionary[u] = tNode
                tNode.appendChild((v, W))
            else:
                tNode = dictionary[u]
                tNode.appendChild((v,W))
                
            if v not in dictionary:
                forParentNode = TreeNode.TreeNode(v)
                dictionary[v] = forParentNode
                forParentNode.appendParent((u, W))
            else:
                forParentNode = dictionary[v]
                forParentNode.appendParent((u,W))
            tree.append((u,v,W))
            subtrees.union(u,v)
    return tree,dictionary