예제 #1
0
def maximum_k(node_list=[], node_length=24, maximum_spacing=3):
    """ Input:
            list of nodes (edges defined implictly by Hamming distances between nodes)
        Output:
            max number of clusters with specified maximum spacing
        Method:
            BRUTE FORCE
            For each node iterate through all permuations of possible n-bit differences  from 1 up to max_spacing - 1.
                For example, for max_spacing = 3, node length 24 bits, the number of permutations is (24 C 1) + (24 C 2) = 300.
    """

    node_set = set(node_list)
    node_list = list(node_set)
    union_find = UnionFind(nodes=node_list)
    bitmasks = get_bitmasks(node_length)

    for node1 in node_list:
        for i in xrange(1, maximum_spacing):
            for permutation in combinations(xrange(node_length), i):
                node2 = node1
                for pos in permutation:
                    node2 ^= bitmasks[pos]
                if node2 in node_set:
                    if union_find.find(node1) != union_find.find(node2):
                        union_find.union(node1, node2)

    return len(set(union_find.leader_lookup.values()))
예제 #2
0
def kruskal(node_list, edge_list):
    edge_list.sort()
    mst = defaultdict(dict)  # minimum spanning tree
    union_find = UnionFind(nodes=node_list)
    for edge in edge_list:
        weight, node1, node2 = edge
        if union_find.find(node1) != union_find.find(node2):
            union_find.union(node1, node2)
            mst[node1][node2] = weight
            mst[node2][node1] = weight
        else:
            continue

    return mst
예제 #3
0
def maximum_spacing(node_list=[], edge_list=[], k=0):
    """ Returns maximum spacing between k clusters"""
    edge_order = []
    # mst = defaultdict(dict)
    union_find = UnionFind(nodes=node_list)

    edge_list.sort()

    for edge in edge_list:
        weight, node1, node2 = edge
        if union_find.find(node1) != union_find.find(node2):
            union_find.union(node1, node2)
            # mst[node1][node2] = weight
            # mst[node2][node1] = weight
            edge_order.append(edge)
        else:
            continue

    return edge_order[-(k - 1)][0]
예제 #4
0
class KruskalGraph(WeightedGraph):
    edges = []
    spanning_tree = []
    components = {}
    union = None

    def __init__(self, graph={}, directed=False, *args, **kwargs):
        super(KruskalGraph, self).__init__(graph, directed, *args, **kwargs)
        self.union = UnionFind()

        # find and insert edges
        for vertex, edges in self.graph.items():
            self.components[vertex] = Node(vertex)

            for edge, weight in edges.items():
                self._add_edge(vertex, edge, weight)

        # sort edges
        self.edges = sorted(self.edges, key=lambda edges: edges[2])

    def build(self):
        """
        Build the MST using Kruskal's Algorithm.
        """
        for x, y, weight in self.edges:
            x_root = self.union.find(self.components[x])
            y_root = self.union.find(self.components[y])

            if x_root != y_root:
                self.spanning_tree.append((x, y, weight))
                self.union.union(x_root, y_root)

    def show(self):
        for edge in self.spanning_tree:
            print edge[0], edge[1], edge[2]

    def _add_edge(self, x, y, weight):
        edge = (x, y, weight)
        reverse_edge = (y, x, weight)

        if edge not in self.edges and reverse_edge not in self.edges:
            self.edges.append((x, y, weight))