class SuperBase:
    superbase = None
    lematizer = None

    def __init__(self, lemat_dict_file):
        self.lematizer = Lematizer(lemat_dict_file)
        self.superbase = UnionFind()

        lemats = self.lematizer.all_lemats()
        for l in lemats:
            self.superbase.make_set(l)

        for (_, lems) in self.lematizer.items():
            sofar = None
            for l in lems:
                if sofar:
                    self.superbase.union(sofar, l)
                sofar = self.superbase.find(l)

    def __getitem__(self, word):
        try:
            # trick
            for lem in self.lematizer[word]:
                break
            # confused?
            # above code is the best way I know to extract an element from the set
            return self.superbase.find(lem)
        except KeyError:
            return word

    def items(self):
        return ((w, self[w]) for (w, _) in self.lematizer.items())
Beispiel #2
0
    def kruskal_mst(self):
        assert self.is_connected(), "Can only find MST of a connected graph"
        uf = UnionFind()
        mst = set()

        for v in self.vs:
            uf.make_set(v)

        half = set()
        for u, v in sorted(self.es):
            if (v, u) not in half:
                half.add((u, v))

        w = 0
        vs = set()
        for u, v in sorted(half, key = lambda e : self.weights[e]):
            if len(vs) == len(self.vs):
                return mst, w

            if uf.find_set(u) != uf.find_set(v):
                uf.union(u, v)
                mst.add((u, v))
                vs.add(u)
                vs.add(v)
                w += self.weights[(u, v)]
Beispiel #3
0
def merge():
    """Merge categories."""
    global mg_ops     # dirty :(
    cats = list(cat_arts.keys())
    uf = UnionFind(cats)
    ncats = len(cat_arts)

    for i in range(0, ncats):
        for j in range(i + 1, ncats):
            cat1, cat2 = cats[i], cats[j]

            if jaccard(cat_arts[cat1], cat_arts[cat2]) > args.threshold:
                uf.union([cat1, cat2])

    sets = uf.sets()
    for group in sets:
        mg_ops += len(group) - 1

        size = 0
        parent = None
        for cat in group:
            l = len(cat_arts[cat])
            if l > size:
                size = l
                parent = cat

        if random.random() >= args.handicap:
            for cat in group:
                if cat != parent:
                    logging.info("MERGE: %s -> %s" % (cat, parent))
                    skill_counts.decr(cat_arts[cat] & cat_arts[parent])
                    cat_arts[parent] |= cat_arts[cat]
                    del cat_arts[cat]
        else:
            logging.info("HANDICAP: Skipping merge of %s -> %s" % (cat, parent))
Beispiel #4
0
def num_similiar_groups_using_union_find(A: List[str]) -> int:
    def is_similiar(w1, w2):
        cnt = 0
        for i1, i2 in zip(w1, w2):
            cnt += (i1 != i2)
            if cnt > 2:
                return False
        return cnt == 2

    uf = UnionFind(A)

    strlen, wordlen = len(A[0]), len(A)
    if wordlen < strlen * strlen:
        for i, w1 in enumerate(A[:-1]):
            for w2 in A[i + 1:]:
                if is_similiar(w1, w2):
                    uf.union(w1, w2)
    else:
        given_words = set(A)
        for w in given_words:
            for i in range(strlen):
                for j in range(i + 1, strlen):
                    new = w[:i] + w[j] + w[i + 1:j] + w[i] + w[j + 1:]
                    if new in given_words:
                        uf.union(w, new)

    return len({uf.find_root(w) for w in uf.p})
Beispiel #5
0
    def __init__(self):
        self.alpha = {}
        self.input = None
        nodei = 0
        with open('clustering.txt') as f:
            self.input = [int(i) for i in f.readline().rstrip().split(' ')]
            for row in f:
                if row.isspace():
                    continue
                hammi = int(row.rstrip().replace(' ', ''), 2)
                if self.alpha.get(hammi, None) is None:
                    self.alpha[hammi] = set([nodei])
                else:
                    self.alpha[hammi].add(nodei)
                nodei += 1

        uf = UnionFind([i for i in range(self.input[0])])
        masks = [0]
        mask_1 = [1 << i for i in range(self.input[1])]
        for i in it.combinations(mask_1, 2):
            masks.append(i[0] ^ i[1])
        masks.extend(mask_1)

        for key in self.alpha:
            for di in masks:
                if self.alpha.get(di ^ key, None) is not None:
                    temp_ = self.alpha[key].union(self.alpha[di ^ key])
                    leader = temp_.pop()
                    for tempi in temp_:
                        uf.union(leader, tempi)
        print(uf.n_comps, uf.n_elts)
Beispiel #6
0
class Tree:
    def __init__(self, directed=False, weighted=False):

        self.directed = directed
        self.weighted = weighted
        self.tree = {}
        self.vertex_num = 0
        self.vertex = []
        self.components = UnionFind()

    def add_edge(self, origin, destiny, weight=0):
        def add_vertex(self, vertex):
            if not vertex in self.tree.keys():
                self.components.add(vertex)
                self.tree[vertex] = {}
                self.vertex_num += 1
                self.vertex.append(vertex)

        if not origin in self.tree.keys():
            add_vertex(self, origin)

        if not destiny in self.tree.keys():
            add_vertex(self, destiny)

        if self.components.connected(origin, destiny):
            raise Exception("Cannot add edge, would create a cicle")

        self.tree[origin][destiny] = weight
        if not self.directed:
            self.tree[destiny][origin] = weight

        self.components.union(origin, destiny)
Beispiel #7
0
    def simplify(self):
        p = copy.deepcopy(self.productions)
        uf = UnionFind(list(p.keys()))
        while True:
            changed = False
            subs = {}
            to_add = {}
            to_delete = set()
            for k1, r1 in p.items():
                for k2, r2 in p.items():
                    if k1 != k2 and k1 not in subs and k2 not in subs and r1 == r2:
                        subs[k2] = k1
                        to_add[k1] = r2
                        to_delete.add(k2)
                        uf.union(k1, k2)
                        changed = True

            p = {**p, **to_add}
            for k in to_delete:
                del p[k]

            if not changed:
                break
            else:
                p = {k2: r2.substitute(subs) for k2, r2 in p.items()}
        return Grammar(productions=p), {k: uf.component(k) for k in p.keys()}
Beispiel #8
0
def equations_possible_using_union_find(equations: List[str]) -> bool:
    uf = UnionFind()
    for leftvar, op, _, rightvar in equations:
        if op == '=':
            uf.union(leftvar, rightvar)
    return not any(op == '!' and uf.is_connect(l, r)
                   for l, op, _, r in equations)
def max_space_clustering(edges, vertices, clusters):
    union_find = UnionFind()
    for vertex in vertices:
        union_find.add_vertex(vertex)
    edges = sorted(edges, key=(lambda x: x.dist))

    e = 0
    for edge in edges:
        rootu = union_find.path_compress_find(edge.u)
        rootv = union_find.path_compress_find(edge.v)

        if e == len(vertices) - clusters:
            if rootu != rootv:
                max_spacing = edge.dist
                break
            else:
                continue

        if rootu == rootv:
            continue
        else:
            union_find.union(edge.u, edge.v)
            e += 1

    root_parents = dict()
    for vertex in list(vertices):
        root_parents[vertex] = union_find.path_compress_find(vertex)

    return root_parents, max_spacing
def get_clusters_two_spaces(graph_nodes):
    union_find = UnionFind()
    for vertex in list(graph_nodes):
        union_find.add_vertex(vertex)
    clusters = len(graph_nodes)
    for u in list(graph_nodes):

        u_neighbours = set(generate_neighbours(u))
        u_second_neighbours = set()
        u_second_neighbours = u_second_neighbours.union(u_neighbours)
        for neighbour in u_neighbours:
            next_neighbours = generate_neighbours(neighbour)
            u_second_neighbours = u_second_neighbours.union(next_neighbours)

        #u_second_neighbours = generate_second_neighbours(u)

        actual_neighbours = set(u_second_neighbours).intersection(graph_nodes)

        for v in actual_neighbours:
            if u == v:
                continue
            root_u = union_find.path_compress_find(u)
            root_v = union_find.path_compress_find(v)
            if root_u == root_v:
                continue
            else:
                clusters -= 1
                union_find.union(root_u, root_v)

    return union_find, clusters
Beispiel #11
0
class Cluster(object):
    """Clusters sets with Jaccard similarity above threshold with high
    probability.

    Algorithm based on Rajaraman, "Mining of Massive Datasets":
    1. Generate set signature
    2. Use LSH to map similar signatures to same buckets
    3. Use UnionFind to merge buckets containing same values
    """
    def __init__(self, width=10, threshold=0.5):
        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())]

    def add_set(self, s, label=None):
        # A label for this set
        if not label:
            label = s

        # Add to unionfind structure
        self.unionfind[label]

        # Get signature
        sig = self.signer.sign(s)

        # Union labels with same LSH key in same band
        for band_idx, hshval in enumerate(self.hasher.hash(sig)):
            self.hashmaps[band_idx][hshval].append(label)
            self.unionfind.union(label, self.hashmaps[band_idx][hshval][0])

    def get_sets(self):
        return self.unionfind.sets()
def combine_boxes(boxes, img_dim, dist_threshold=15, padding=0):
    """Uses UnionFind to group close-by contours into boxes (disjoint
    connected components).

    Parameters:
    boxes (list(numpy array)): List of numpy arrays of coordinates of a
    box as returned by enclosing_box.
    img_dim (tuple(int)): Tuple of image dimensions.
    dis_threshold (int): Threshold of number of pixels to determine
    whether boxes are too close.
    padding (int): Number of pixels that are padding.

    Return:
    (numpy array): Numpy array of combined boxes.
    """
    n = len(boxes)
    uf = UnionFind(n)

    for i, j in combinations(range(n), 2):
        if closest_distance(boxes[i], boxes[j]) < dist_threshold:
            uf.union(i, j)

    box_groups = [[box for i in group for box in boxes[i]]
                  for group in uf.groups()]
    combined_boxes = [
        enclosing_box(group, img_dim, padding=padding) for group in box_groups
    ]
    filtered_boxes = [x for x in combined_boxes if fits_criteria_box(x)]
    return np.array(filtered_boxes)
Beispiel #13
0
def kruskal(edges):
    """Calculate the cost and edges of a spanning tree, given the edges of
       a graph. Complexity: O(|E| log |E|)
    """
    # Find all the nodes and create a heap of edges - O(|E|)
    all_nodes = set()
    hq = []
    for i, j, w in edges:
        all_nodes.add(i)
        all_nodes.add(j)
        heappush(hq, (w, i, j))

    # Initialize the forest - O(|V|)
    forest = UnionFind(all_nodes)

    # Initialize the tree's data structure - O(1)
    tree_edges = []
    cost = 0

    # Calculate the minimum spanning tree - O(|E| log |E|)
    while hq:
        cost_incr, n1, n2 = heappop(hq)
        if forest.is_same_set(n1, n2):
            continue
        cost += cost_incr
        forest.union(n1, n2)
        tree_edges.append((n1, n2))

    return (tree_edges, cost)
Beispiel #14
0
def find_circle_num_using_union_find(M: List[List[int]]) -> int:
    uf = UnionFind(len(M))
    for i in range(uf.num):
        # ignore upper-right triangle in matrix
        for j in range(0, i):
            if M[i][j] == 1:
                uf.union(i, j)

    return len([1 for i, v in enumerate(uf.parent) if i == v])
Beispiel #15
0
 def UnionFindCommunity(self, G):
     Nodes = G.nodes()
     uf = UnionFind(Nodes)
     for source, target in G.edges():
         uf.union(source, target)
     components = uf.components()
     score = []
     for nodes in components:
         score.append(nodes)
     self.addGNodesAttr(G, score, "Union find")
def trip_roster_merged(trip_roster_file, colname_file, trip_chain,
                       park_pair_file, gas_pair_file):
    col_names = pd.read_csv(colname_file)
    trip_roster = pd.read_csv(trip_roster_file,
                              header=None,
                              names=col_names.columns)
    if trip_chain == False:
        matched_trip_pair = pd.read_csv(park_pair_file)
        matched_trip_pair.columns = [
            'TripId', 'StopId', 'EndTripId', 'StartTripId'
        ]
        matched_trip_pair = matched_trip_pair[[
            'EndTripId', 'StartTripId', 'StopId'
        ]].append(pd.read_csv(gas_pair_file))
        trip_pair_id = ['EndTripId', 'StopId', 'StartTripId']
        new_pair_df = matched_trip_pair
    else:
        matched_trip_pair = pd.read_csv(park_pair_file,
                                        usecols=['end', 'start'])
        matched_trip_pair.columns = ['EndTripId', 'StartTripId']
        matched_trip_pair = matched_trip_pair.append(
            pd.read_csv(gas_pair_file, usecols=['EndTripId', 'StartTripId']))
        trip_pair_id = ['EndTripId', 'StartTripId']
        # trip chaining
        start_time = time.time()
        uf = UnionFind(list(set(matched_trip_pair.values.flatten())))
        for index, row in matched_trip_pair.iterrows():
            uf.union(row['EndTripId'], row['StartTripId'])
        result = uf.components()
        print('Trip chaining takes %s secs for %s trip pairs.' %
              (time.time() - start_time, len(matched_trip_pair)))

        def set_first_last(input_set):
            tmp = list(input_set)
            return [tmp[0], tmp[-1]]

        new_pair = map(set_first_last, result)
        new_pair_df = pd.DataFrame(new_pair,
                                   columns=['EndTripId', 'StartTripId'])
    trip_unmatched = trip_roster.loc[~trip_roster['TripId'].isin(
        matched_trip_pair[['EndTripId', 'StartTripId']].values.flatten())]
    # create od file for matched trips/ trip chain
    trip_od = new_pair_df.merge(
        trip_roster[['TripId', 'StartLocLat',
                     'StartLocLon']].rename(columns={'TripId': 'EndTripId'}),
        how='left',
        sort=False)
    trip_od = trip_od.merge(
        trip_roster[['TripId', 'EndLocLat',
                     'EndLocLon']].rename(columns={'TripId': 'StartTripId'}),
        how='left',
        sort=False)
    trip_od['TripId'] = trip_od[trip_pair_id].apply(
        lambda row: '_'.join(row.tolist()), axis=1)
    return trip_unmatched, trip_od
def clustering(edge_list, count_nodes, clusters):
    u = UnionFind([x+1 for x in range(count_nodes)])
    count_edges = len(edge_list)
    i = 0
    while True:
        if not u.find(edge_list[i][1][0]) == u.find(edge_list[i][1][1]):
            if count_nodes <= clusters:
                return edge_list[i][0], u
            u.union(edge_list[i][1][0], edge_list[i][1][1])
            count_nodes -= 1
        i += 1
Beispiel #18
0
def rm_stones_using_union_find(stones: List[List[int]]) -> int:
    if not stones:
        return 0

    uf = UnionFind()
    for x, y in stones:
        for i, j in stones:
            if x == i or y == j:
                uf.union(10000 * x + y, 10000 * i + j)

    return len(uf.p) - len({uf.find_root(10000 * x + y) for x, y in stones})
Beispiel #19
0
def kruskal(g, w):
    uf = UnionFind(g.keys())
    w = sorted(w, key=lambda x: w[x])
    edges = list()
    for edge in w:
        a, b = edge
        if not uf.connected(a, b):
            uf.union(a, b)
            edges.append(edge)
        if len(edges) == len(g) - 1:
            break
    return edges
Beispiel #20
0
def longest_consecutive_by_uf(nums: List[int]) -> int:
    if not nums:
        return 0

    uf = UnionFind(nums)
    valToIdx = {nums[i]: i for i in range(len(nums))}
    for v in valToIdx.keys():
        # When get value == 0, which is false,
        # so always check None instead of false,
        #   otherwise may cause union operations is missing
        if valToIdx.get(v + 1) is not None:
            uf.union(valToIdx[v], valToIdx[v + 1])
    return uf.largest_one_union()
Beispiel #21
0
  def mspEdges(self, heuristicFn):
    A = []
    N = len(self.nodes)
    uf = UnionFind(N)
    weights = self.generate_weights(heuristicFn)

    order = argsort(weights)
    for i in order:
      (u,v) = self.edges[i]
      if not uf.connected(u,v):
        A.append((u,v))
        uf.union(u,v)
    return A
Beispiel #22
0
    def mspEdges(self, heuristicFn):
        A = []
        N = len(self.nodes)
        uf = UnionFind(N)
        weights = self.generate_weights(heuristicFn)

        order = argsort(weights)
        for i in order:
            (u, v) = self.edges[i]
            if not uf.connected(u, v):
                A.append((u, v))
                uf.union(u, v)
        return A
Beispiel #23
0
def kclustering(nodes):
    """ clustering the nodes by hamming distance """
    clusters = UnionFind(nodes)
    for num in nodes:
        for code in hamming1(num):
            if code in nodes:
                clusters.union(num, code)

        for code in hamming2(num):
            if code in nodes:
                clusters.union(num, code)

    return len(clusters.subtree.keys())
Beispiel #24
0
def accounts_merge_using_union_find(
        accounts: List[List[str]]) -> List[List[str]]:

    uf = UnionFind()
    email_to_name = dict()

    for account in accounts:
        name = account[0]
        for email in account[1:]:
            email_to_name[email] = name
            uf.union(email, account[1])

    return [[email_to_name[pmail]] + sorted(emails)
            for (pmail, emails) in uf.groups().items()]
Beispiel #25
0
def gen_model(dataset_name):
    event_data, missing_urls_amount = load_data(dataset_name)

    ##########

    _info(
        "create pairs (t, u) or (t, t') for each tweet t and url u or replied/retweeted tweet t'"
    )
    replies_amount = 0
    retweets_amount = 0
    quotes_amount = 0
    missing_replies_amount = 0
    pairs = []
    for tweet_id, tweet in event_data.items():
        [
            pairs.append((tweet_id, url))
            for url in tweet.expanded_urls.values() if url
        ]

        # retweets ARE considered, due to be exact text copies of the retweeted tweet
        if tweet.retweet_id != 'NULL':
            retweets_amount += 1
        if tweet.quote_id != 'NULL':
            quotes_amount += 1
        if tweet.reply_id != 'NULL':
            replies_amount += 1
            if tweet.reply_id in event_data:
                pairs.append((tweet_id, tweet.reply_id))
            else:
                missing_urls_amount += 1
    _info(
        f'total pairs: {len(pairs)}, retweets: {retweets_amount}, quotes: {quotes_amount}, replies: {replies_amount} '
        f'(missing: {missing_replies_amount})')

    ##########
    """
        all keys must be the same time (in this case, strings);
        unionfind will vectorize operations and will cast everything in the array to the same type,
        so if there are integers and strings, it will cast everything to string and comparisons will fail
        when calling uf.components().
    """

    _info('applying union-find')
    uf = UnionFind()
    for u, v in pairs:
        uf.union(u, v)
    _info(f'total components: {len(uf.components())}')

    return uf, event_data
Beispiel #26
0
    def test_union(self):
        u = UnionFind()
        foo = Node("foo")
        u.add(foo)

        bar = Node("bar")
        u.add(bar)

        self.assertEqual(foo, u.find(foo))
        self.assertEqual(bar, u.find(bar))

        u.union(foo, bar)

        self.assertEqual(bar, u.find(foo))
        self.assertEqual(bar, u.find(bar))
Beispiel #27
0
def find_num_islands_with_uf(grid: List[List[str]]) -> int:
    if not grid:
        return 0

    uf = UnionFind(grid)
    r, c = len(grid), len(grid[0])
    for i in range(r):
        for j in range(c):
            if grid[i][j] == '1':
                # check its right neighbor till right bound
                if j + 1 < c and grid[i][j + 1] == '1':
                    uf.union(i * c + j, i * c + j + 1)
                # check its down neighbor till down bound
                if i + 1 < r and grid[i + 1][j] == '1':
                    uf.union(i * c + j, c * (i + 1) + j)
    return uf.count
Beispiel #28
0
def cluster(edges, start_at):
    uf = UnionFind()

    sortede = sorted(edges, key=lambda x: x[3])

    for k in range(1, 501):
        uf.add(k)

    for _, u, v, w in sortede:

        if len(list(uf.components())) == 4:
            break
        elif not uf.connected(u, v):
            uf.union(u, v)

    find_minimal(uf, edges)
Beispiel #29
0
def cluster(graph, k):
    edges = heapify(graph.edges)

    u = UnionFind()
    [u.add(node) for node in graph.nodes.values()]

    while u.clusters > k:
        cost, edge = heappop(edges)
        if cycle(u, edge):
            #print "skipping {}".format(edge)
            pass
        else:
            u.union(u.find(edge.v0), u.find(edge.v1))

    mindist = get_mindist(u, edges)
    return mindist, u.followers
def Clustering(nodes):

    UnionNodes = UnionFind(nodes.keys())


    for node in tqdm(nodes):

        for neighbour in getNeiborhood(node):

            if neighbour not in nodes:
                continue
            
            if not UnionNodes.connected(node, neighbour):
                UnionNodes.union(node, neighbour)

    
    return UnionNodes
Beispiel #31
0
    def kruskal(self):
        queue = PriorityQueue()
        mst = list()
        mst_weight = 0
        uf = UnionFind(len(self.vertexes))

        for edge in self.edges:
            queue.put(edge)

        while not queue.empty() and len(mst) < self.size:
            current_edge = queue.get()

            if not uf.find(self.vertexes[current_edge.origin].index, self.vertexes[current_edge.dest].index):
                uf.union(self.vertexes[current_edge.origin].index, self.vertexes[current_edge.dest].index)
                mst.append(current_edge)
                mst_weight += current_edge.weight

        return mst, mst_weight
Beispiel #32
0
    def clustering(self, groups, minheap):
        #maxheap is a max heap of edges (one direction only)
        unionfind = UnionFind(list(self.graph.keys()))
        while unionfind.size() > groups:
            #keep merging until number of desired groups reached
            curr = minheap.pop()
            curr_edge = curr.get_data()
            if unionfind.find(curr_edge[0]) == unionfind.find(curr_edge[1]):
                #same group
                continue
            unionfind.union(curr_edge[0], curr_edge[1], True)
        while unionfind.find(curr_edge[0]) == unionfind.find(curr_edge[1]):
            #pop until different groups to get max distance, because next edge might be within a group
            minheap.pop().get_data()
            curr_edge = minheap.peek().get_data()

        #smallest distance is the edge at the top of max heap since they are in different groups
        return unionfind, minheap.peek().get_key()
Beispiel #33
0
def cluster(nodes):
    uf = UnionFind()
    one_diff, two_diff = one_two_away()

    for v in nodes:
        uf.add(v)

    for vindex, v in enumerate(nodes):

        # squash all the nodes with distance 1 away into me
        od = [(v ^ i) for i in one_diff]
        td = [(v ^ i) for i in two_diff]
        for d in od + td:
            if d in nodes and not uf.connected(v, d):
                uf.union(v, d)
                print("smashed", v, d)

    print(len(list(uf.components())))
Beispiel #34
0
def prim(g, w, start):
    edges = list()
    uf = UnionFind(g.keys())
    q = list()

    for child in g[start]:
        heappush(q, [w[(start, child)], (start, child)])

    while len(edges) < len(g) - 1:
        weight, (a, b) = heappop(q)
        if not uf.connected(a, b):
            edges.append((a, b))
            uf.union(a, b)
            for child in g[b]:
                if child != a:
                    heappush(q, [w[(b, child)], (b, child)])

    return edges
Beispiel #35
0
def cluster(vertices, radix):
    V = frozenset(vertices)
    u = UnionFind()
    for v in V:
        u.add(v)
    print "Starting with {} clusters".format(u.clusters)
    i = 0.0
    for v in V:
        if i % 100 == 0:
            p = 100*( i / len(vertices))
            sys.stdout.write("\r%f%% (%d)" % (p, len(V)))
            sys.stdout.flush()
        potential = hamming_neighbours(v, radix=radix, dist=2)
        for p in potential:
            if p in V:
                neighbour = p
                u.union(v, neighbour)

        i += 1
    sys.stdout.write("\n")
    return u
Beispiel #36
0
    def recolor_by_connected_components(self):
        from unionfind import UnionFind
        uf = UnionFind()

        for t in self.gtm.times:
            for g in self.gtm.time[t]:
                uf.find(g)
            for i in self.gtm.inds:
                uf.find((i,t))

            for g in self.gtm.time[t]:
                for i in self.gtm.group[g]:
                    if self.group_color[g-1]==self.ind_color[i-1][t-1]:
                        uf.union(g, (i,t))
                        leader = uf.find(g)
            if t>1:
                for i in self.gtm.inds:
                    if self.ind_color[i-1][t-1]==self.ind_color[i-1][t-2]:
                        uf.union((i,t-1), (i,t))
                        leader = uf.find((i,t-1))

        new_color = {}
        for t in self.gtm.times:
            for g in self.gtm.time[t]:
                leader = uf.find(g)
                if leader not in new_color:
                    new_color[leader] = len(new_color)+1
            for i in self.gtm.inds:
                leader = uf.find((i,t))
                if leader not in new_color:
                    new_color[leader] = len(new_color)+1

        for g in self.gtm.groups:
            self.group_color[g-1] = new_color[uf.find(g)]
        for i in self.gtm.inds:
            for t in self.gtm.times:
                self.ind_color[i-1][t-1] = new_color[uf.find((i,t))]
 def mst(self,b_lengths, weights):
     """Kruskal's algorithm for minimum spanning tree 
     Input:
         b_lengths: dictionary with keys (node,node) and values branch length
         weights: dictionary maps (node,node) to negative log likelihood
     Output:
         adj_mat: adjacency matrix. dict (node,node) keys weight values
     """
     #go through all the nodes and get rid of parent/child relationships
     #so we can build the tree again
     #except keep leaf nodes and observed data
     for i in range(len(self.nodes)):
         if len(self.nodes[i].children) > 1:
             self.nodes[i].parent = None
             self.nodes[i].parent_weight = None
             self.nodes[i].children = []
         else:
             self.nodes[i].parent = None
             self.nodes[i].parent_weight = None                
         
     #unionfind object
     d_set = UnionFind()
     #sort the edges into non-decreasing order
     edges = [(edge,weight) for edge,weight in 
                 sorted(weights.items(),key = lambda x: x[1])]
     #keep track of new graph as an adjacency matrix
     adj_mat = {}
     for edge,weight in edges:
         u,v = edge
         if d_set[u] != d_set[v]:
             d_set.union(u,v)
             #update adjacency matrix
             adj_mat[(u,v)] = b_lengths[(u,v)]
             adj_mat[(v,u)] = b_lengths[(u,v)]
     
     return(adj_mat)
Beispiel #38
0
class Edge(object):
    def __init__(self, node1, node2, cost=0, marked=None):
        self.node1 = node1
        self.node2 = node2
        self.cost = cost
        self.marked = marked

    def __cmp__(self, y):
        return self.cost - y.cost
    
    def __repr__(self):
        return '<Edge(%s, %s), cost:%s>' % (self.node1, self.node2, self.cost)

f = open('./edges.txt', 'r')
n_nodes, n2 = f.readline().strip().split()
edges = []
for l in f:
    a, b, c = l.split()
    edges.append(Edge(str(a), str(b), cost=int(c)))
edges = sorted(edges, key=lambda x: x.cost)
U = UnionFind()
T = []
for e in edges:
    if U[e.node1] != U[e.node2]:
        T.append(e)
        U.union(e.node1, e.node2)
print sum(e.cost for e in T)


Beispiel #39
0
class Cluster(object):
    """Clusters sets with Jaccard similarity above threshold with high
    probability.

    Algorithm based on Rajaraman, "Mining of Massive Datasets":
    1. Generate set signature
    2. Use LSH to map similar signatures to same buckets
    3. Use UnionFind to merge buckets containing same values
    """
    def __init__(self, minHashLen=13, numRowsInBucket=2, threshold=None):
        self.unionfind = UnionFind()
        self.signer = MinHashSignature(minHashLen)
        self.hasher = LSH(minHashLen, numRowsInBucket, threshold)
        self.hashmaps = [defaultdict(list)
                         for _ in range(self.hasher.get_n_bands())]
        self.lshmap = {}

    def add_set(self, s, label=None):
        # A label for this set
        if not label:
            label = s

        # Add to unionfind structure
        self.unionfind[label]

        # Get signature
        sig = self.signer.sign(s)

        # Union labels with same LSH key in same band
        lshKeys = self.hasher.hash(sig)
        self.lshmap[label] = []

        for band_idx, hshval in enumerate(lshKeys):
            #print "Got band_idx, hashval: " + str(band_idx) + "," + str(hshval)
            self.hashmaps[band_idx][hshval].append(label)
            self.unionfind.union(label, self.hashmaps[band_idx][hshval][0])
            self.lshmap[label].append(hshval)

    def get_clusters(self, min_cluster_len):
        for band_idx in range(0,len(self.hashmaps)):
            #print "clusters>Got band_idx: " + str(band_idx)
            hashmap = self.hashmaps[band_idx]
            for key in hashmap:
                list = hashmap[key]
                if(len(list) > min_cluster_len):
                    yield list

    def get_clusters_with_hashes(self, min_cluster_len):
        for band_idx in range(0,len(self.hashmaps)):
            hashmap = self.hashmaps[band_idx]
            for key in hashmap:
                list = hashmap[key]
                if(len(list) > min_cluster_len):
                    list2 = []
                    for label in list:
                        if self.lshmap[label]:
                            list2.append((label, self.lshmap[label]))
                        else:
                            list2.append(label)
                    yield list2

    def get_cluster_unions(self, min_cluster_len):
        x = self.unionfind.sets()
        for set in x:
            if len(set) > min_cluster_len:
                yield set

    def get_min_hash(self, object):
        return list(self.signer.sign(object))

    def get_lsh_hash(self, object):
        sig = self.signer.sign(object)
        return list(self.hasher.hash(sig))
Beispiel #40
0
def makeUnionFind(_set,N):
    uf = UnionFind(N)
    for i,j in _set:
        uf.union(i,j)
    return uf
Beispiel #41
0
# find connected components which have to be paths
# wanna check if they are paths?
uf = UnionFind()
for line in f.readlines():
	line = line.strip()
	if line.startswith("# y"): break
	if line=="" or line.startswith("#"): continue
	if line.find(',')>=0: line = line.split(',')
	elif line.find(' ')>=0: line = line.split(' ')
	else: raise Exception("Invalid line: "+line)
	if len(line)>=2:
		u,v = int(line[0]), int(line[1])
	else:
		raise Exception("ERROR line: %s"%line)
	uf.union(u,v)

# make lists of groups (no dummies) in each component
vertices = range(1, group_count+1)
component = {}
for v in vertices:
	l = uf.find(v)
	if l not in component:
		component[l] = list()
	component[l].append(v)
for l in component:
	component[l].sort()
component = sorted(component.values())

# build color-conflict graph
adj_list = {}
Beispiel #42
0
def maze(w, h, size=2):
    def conv_size(n):
        return (n - 1) // size + 1

    nw, nh = conv_size(w), conv_size(h)
    ns = size // 2 - 1
    uf = UnionFind(nw * nh)
    lab = Labyrinth(w, h)

    for x in range(w):
        for y in range(h):
            lab[x, y] = 0

    edges = []
    for i in range(nh - 1):
        for j in range(nw - 1):
            f = flatten(i, j, nw, nh)
            edges.append((f, f + 1))  # right
            edges.append((f, f + nw))  # down

    for i in range(nh - 1):
        f = flatten(i, nw - 1, nw, nh)
        edges.append((f, f + nw))  # down

    for j in range(nw - 1):
        f = flatten(nh - 1, j, nw, nh)
        edges.append((f, f + 1))  # right

    shuffle(edges)

    while len(uf) > 1:
        u, v = edges.pop()
        y1, x1 = unflatten(u, nw, nh)
        y2, x2 = unflatten(v, nw, nh)
        if uf.find(u) != uf.find(v):
            uf.union(u, v)
            if x2 - x1 == 1:
                for i in range(size + 1):
                    for j in range(1, ns + 1):
                        ny = size * y1 - j
                        if ny >= 0:
                            lab[size * x1 + i, ny] = True
                        else:
                            break
                    lab[size * x1 + i, size * y1] = True
                    for j in range(1, ns + 1):
                        ny = size * y1 + j
                        if ny < h:
                            lab[size * x1 + i, ny] = True
                        else:
                            break
            else:
                for i in range(size + 1):
                    for j in range(1, ns + 1):
                        nx = size * x1 - j
                        if nx >= 0:
                            lab[nx, size * y1 + i] = True
                        else:
                            break
                    lab[size * x1, size * y1 + i] = True
                    for j in range(1, ns + 1):
                        nx = size * x1 + j
                        if nx < w:
                            lab[nx, size * y1 + i] = True
                        else:
                            break

    lab[0, 0] = 1
    lab.start = 0, 0
    lab[lab.w - 2, lab.h - 2] = 1
    lab.goal = lab.w - 2, lab.h - 2

    return lab