示例#1
0
class ClusterGraph():
    def __init__(self):
        self.edges = []
        self.union_find = UnionFind()

    def add_edge(self, edge):
        self.edges.append(edge)
        self.union_find.add_element(edge[0])
        self.union_find.add_element(edge[1])

    def clusterfy(self, num_clusters=4):
        self.sort_edges()
        while len(self.union_find.clusters) > num_clusters:
            edge = self.edges.pop()
            leader1 = self.union_find.find(edge[0])
            leader2 = self.union_find.find(edge[1])
            if leader1 != leader2:
                self.union_find.union(leader1, leader2)

    def sort_edges(self):
        self.edges.sort(key=lambda edge: edge[2], reverse=True)

    def get_maximum_spacing(self):
        final_edges = []
        for edge in self.edges:
            leader1 = self.union_find.find(edge[0])
            leader2 = self.union_find.find(edge[1])
            if leader1 != leader2:
                final_edges.append(edge)

        return min(final_edges, key=lambda edge: edge[2])[2]
class ClusterNodesOnly():
    def __init__(self):
        self.union_find = UnionFind()
        self.one_distances = []
        self.two_distances = []

    def find_all_one_distances(self, node):
        possible_nodes = []
        for bit in range(0, len(node)):
            search_node = node.copy()
            bit_to_change = "0" if node[bit] == '1' else "1"
            search_node[bit] = bit_to_change
            if tuple(search_node) in self.union_find.node_leaders:
                possible_nodes.append(search_node)

        return possible_nodes

    def find_all_two_distances(self, node):
        possible_nodes = []
        for first_bit in range(0, len(node) - 1):
            for second_bit in range(1, len(node)):
                search_node = node.copy()
                first_bit_to_change = "0" if node[first_bit] == "1" else "1"
                second_bit_to_change = "0" if node[second_bit] == "1" else "1"
                search_node[first_bit] = first_bit_to_change
                search_node[second_bit] = second_bit_to_change
                if tuple(search_node) in self.union_find.node_leaders:
                    possible_nodes.append(search_node)

        return possible_nodes

    def add_node(self, node):
        self.union_find.add_element(tuple(node))
        one_distances = self.find_all_one_distances(node)
        for close_node in one_distances:
            self.one_distances.append((node, close_node))
        two_distances = self.find_all_two_distances(node)
        for close_node in two_distances:
            self.two_distances.append((node, close_node))

    def clusterfy(self):
        while len(self.one_distances) > 0 or len(self.two_distances) > 0:
            nodes = self.get_next_pair_of_nodes()
            leader1 = self.union_find.find(tuple(nodes[0]))
            leader2 = self.union_find.find(tuple(nodes[1]))
            if leader1 != leader2:
                self.union_find.union(tuple(leader1), tuple(leader2))
        return len(self.union_find.clusters)

    def get_next_pair_of_nodes(self):
        if len(self.one_distances) > 0:
            return self.one_distances.pop()
        elif len(self.two_distances) > 0:
            return self.two_distances.pop()
        else:
            return None