Exemplo n.º 1
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)
Exemplo n.º 2
0
    def findCircleNum(self, M):
        """
        :type M: List[List[int]]
        :rtype: int
        """
        length =len(M)
        uf = UnionFind(length)
        for i in range(length):
            for j in range(i):
                if M[i][j] == 1:
                    uf.add(i,j)

        return uf.componentsNum()
Exemplo n.º 3
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))
def hammond_distances(file_path):
    file_stream = open(file_path)
    line_one = file_stream.readline().split(' ')
    count_edges, count_bits = int(line_one[0]), int(line_one[1])
    uf = UnionFind([])
    for i in range(count_edges):
        code = file_stream.readline()
        code = code.replace(' ', '').replace('\n', '')
        uf.add(code)
        update_singles(uf, code, count_bits)
        update_doubles(uf, code, count_bits)
    file_stream.close()
    clusters = set()
    for k in uf._node_titles.keys():
        clusters.add(uf.find(k))
    return len(clusters)
Exemplo n.º 5
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)
Exemplo n.º 6
0
    def test_add_node(self):
        u = UnionFind()
        foo = Node("foo")
        bar = Node("bar")
        baz = Node("baz")
        u.add(foo)
        u.add(bar)
        u.add(baz)
        self.assertEqual(3, len(u.leader))
        self.assertEqual(foo, u.leader[foo])
        self.assertEqual(bar, u.leader[bar])
        self.assertEqual(baz, u.leader[baz])

        self.assertEqual(3, len(u.followers))
        self.assertEqual(set(), u.followers[foo])
        self.assertEqual(set(), u.followers[bar])
        self.assertEqual(set(), u.followers[baz])
Exemplo n.º 7
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())))
Exemplo n.º 8
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
Exemplo n.º 9
0
def persistence(f):
    def mergeF(a, b):
        m, e = max((a['max'], a['elder']), (b['max'], b['elder']))
        return {'max': m, 'elder': e}

    fi = sorted(list(zip(f, range(len(f)))), reverse=True)
    uf = UnionFind(mergeF)
    pairs = []
    for v, i in fi:
        uf.add(i, {'max': v, 'elder': i})
        if i - 1 in uf.V and i + 1 in uf.V:
            a = uf.getData(i - 1)
            b = uf.getData(i + 1)
            d, j = min((a['max'], a['elder']), (b['max'], b['elder']))
            pairs.append((d - v, i, j))
        if i - 1 in uf.V:
            uf.merge(i - 1, i)
        if i + 1 in uf.V:
            uf.merge(i, i + 1)
    pairs.append((float('inf'), None, fi[0][1]))
    return pairs
Exemplo n.º 10
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
Exemplo n.º 11
0
class Map:
    # cities = {}
    # _loops = []
    # _borders = []
    # loops = UnionFind()
    # _print: bool = False

    def __init__(self, cities_data, data_limit: int = 0, print: bool = False):
        self.cities = {}
        self._loops = []
        self._borders = []
        self.loops = UnionFind()
        limit = data_limit
        self._print = print
        df = pd.read_csv(cities_data)
        upper = len(df)
        if limit != 0:
            upper = limit
        df = df[0:upper]

        for row in df.iterrows():
            city = City(row[1].CityId, row[1].X, row[1].Y)
            self.cities[city.id] = city
        self._create_loops()

    def _create_loops(self):
        points = []
        g_cities = nx.DiGraph()

        for city in self.cities:
            city = self.cities.get(city)
            g_cities.add_node('f-' + str(city.id), bipartite=0)
            g_cities.add_node('t-' + str(city.id), bipartite=1)
            points.append([city.x, city.y])
        points = np.array(points)
        vor = Voronoi(points, incremental=True)

        for point in vor.ridge_points:
            self.cities[point[0]].add_neighbor(self.cities[point[1]])
            self.cities[point[1]].add_neighbor(self.cities[point[0]])
            g_cities.add_edge('f-' + str(self.cities[point[0]]),
                              't-' + str(self.cities[point[1]]))
            g_cities.add_edge('f-' + str(self.cities[point[1]]),
                              't-' + str(self.cities[point[0]]))

        temp = bipartite.maximum_matching(g_cities)
        print(temp)
        del g_cities
        islands = nx.DiGraph()
        i = 0
        for key, value in temp.items():
            # connect cities ...
            self.cities[int(key[2:])].connect_to(self.cities[int(value[2:])])
            islands.add_edge(self.cities[int(key[2:])],
                             self.cities[int(value[2:])])
            i += 1
            if (i >= temp.__len__() / 2):
                break
        for i, c in enumerate(nx.recursive_simple_cycles(islands)):
            # for i, c in enumerate(nx.simple_cycles(islands)):
            loop = Loop(c, i)
            self._loops.append(loop)
            self.loops.add(i)

        # plt.subplot(121)
        # nx.draw(islands, with_labels=True)
        # plt.savefig('temp_diagram.png')
        # plt.show()

    def loops_borders(self):
        temp_h = []
        n = len(self.loops)
        for i in range(n):
            for j in range(i + 1, n):
                temp_h = self._loops[i].find_border(self._loops[j], temp_h)
        return temp_h

    def merge_loops(self):
        city_pairs = self.loops_borders()
        while (city_pairs.__len__() > 0):
            cp = hq.heappop(city_pairs)
            if (not (self.loops.connected(cp[1].loop_id, cp[2].loop_id))):
                # connect loops
                if (self.merge_node(cp[1], cp[2])):
                    self.loops.union(cp[1].loop_id, cp[2].loop_id)

    def merge_node(self, c1: City, c2: City):
        p = c1
        q = c2
        if (self.is_revers(c1, c2)):
            p = c2
            q = c1
        self.connect(q.prev, p.next)
        self.connect(p, q)
        return True

    def connect(self, p: City, q: City) -> bool:
        p.next = q
        q.prev = p
        if (self._print):
            print(str(p.id) + ' --> ' + str(q.id))

    def is_revers(self, c1: City, c2: City):
        dist_12 = c2.prev.sqr_dist_to(c1.next)
        dist_21 = c1.prev.sqr_dist_to(c2.next)
        return dist_12 > dist_21

    def print_loops(self):
        print('loops ...')
        for loop in self._loops:
            print('------------')
            for vertex in loop.cities:
                print(
                    str(loop.cities.get(vertex)) + '\tEnergy: ' +
                    str(loop.cities.get(vertex).energy))

    def print_path(self):
        current_city = self.cities[0]
        current_energy = 10
        dist = 0
        min_enrg = 10
        while True:
            d = current_city.dist_to(current_city.next)
            if (min_enrg > current_energy):
                min_enrg = current_energy
            if (current_energy <= 0):
                d = d * 1.1
            dist += d
            print(str(current_city.id))
            # print(str(current_city.id)+'\tE: '+str(current_energy))
            current_city = current_city.next
            if (current_city.next == self.cities[0]):
                print(current_city.id)
                break
            current_energy += -1
            if (current_city.is_prime):
                current_energy = 10
        print('Distance: ' + str(dist))
        print('Minimum Energy:' + str(min_enrg))

    def save_path(self, file_name: str = "myFile.csv"):
        f = open(file_name, "w")
        f.write('Path\n')
        current_city = self.cities[0]
        while True:
            f.write(str(current_city.id) + '\n')
            current_city = current_city.next
            if (current_city.next == self.cities[0]):
                f.write(str(current_city.id) + '\n')
                break
        f.write('0\n')

    def save_paths(self, file_name: str = "myFile.csv"):
        f = open(file_name, "w")
        f.write('Path\n')
        current_city = self.cities[0]
        current_energy = 10
        dist = 0
        min_enrg = 10
        while True:
            d = current_city.dist_to(current_city.next)
            if (min_enrg > current_energy):
                min_enrg = current_energy
            if (current_energy <= 0):
                d = d * 1.1
            dist += d
            f.write(str(current_city.id) + '\n')
            current_city = current_city.next
            if (current_city.next == self.cities[0]):
                f.write(str(current_city.id) + '\n')
                break
            current_energy += -1
            if (current_city.is_prime):
                current_energy = 10
        f.write('0\n')
        print('Distance: ' + str(dist))
        return {'totalDist': dist, 'minEnergy': min_enrg}
Exemplo n.º 12
0
 def test_find(self):
     u = UnionFind()
     foo = Node("foo")
     u.add(foo)
     self.assertEqual(foo, u.find(foo))