示例#1
0
    def binary2treegraph(self, chromosome):
        '''Converts from BinaryChromosome to TreeChromosome'''

        GRAPH = self.STPG.graph

        queue = PriorityQueue()
        disjointset = DisjointSets()
        subgraph = UGraph()
        dones = set()

        # todos os vértices esperados na solução parcial
        vertices = self.vertices_from_chromosome(chromosome)

        # adiciona uma aresta se os vértices extremos da aresta
        # estão contidos no conjunto vertices
        # mantém essas arestas em uma fila de prioridades para
        # formar uma MST baseado no algoritmo de Kruskal
        for v in vertices:
            dones.add(v)
            disjointset.make_set(v)  # para construir a MST
            subgraph.add_node(v)  # garantir a inserção de um vértice isolado
            for u in GRAPH.adjacent_to(v):
                if (u in vertices) and (u not in dones):
                    weight = GRAPH.weight(v, u)
                    queue.push(weight, (v, u))

        while queue:
            v, u = queue.pop()
            if disjointset.find(v) != disjointset.find(u):
                subgraph.add_edge(v, u)
                disjointset.union(v, u)

        return subgraph
示例#2
0
    def __call__(self, parent_a, parent_b):
        assert isinstance(
            parent_a, EdgeSet
        ), f'parent_a has to be EdgeSet type. Give was {type(parent_a)}'
        assert isinstance(
            parent_b, EdgeSet
        ), f'parent_b has to be EdgeSet type. Give was {type(parent_b)}'

        edges = parent_a | parent_b

        done = DisjointSets()
        for v in edges.vertices:
            done.make_set(v)

        edges = set(edges)

        result = EdgeSet()
        while edges and len(done.get_disjoint_sets()) > 1:
            edge = sample(edges, k=1)[0]
            y, z = edge[0], edge[1]
            if done.find(y) != done.find(z):
                result.add(edge)
                done.union(y, z)
            edges.discard(edge)

        return result
示例#3
0
    def __call__(self, red, blue):
        assert isinstance(
            red, UGraph), f'red parent must be UGraph. Given {type(red)}'
        assert isinstance(
            blue, UGraph), f'blue parent must be UGraph. Given {type(blue)}'

        done = DisjointSets()

        union_g = UGraph()
        for v, u in red.gen_undirect_edges():
            union_g.add_edge(v, u)
        for v, u in blue.gen_undirect_edges():
            union_g.add_edge(v, u)

        for v in union_g.vertices:
            done.make_set(v)

        all_edges = set()
        for edge in union_g.gen_undirect_edges():
            all_edges.add(edge)

        result = UGraph()
        while all_edges and len(done.get_disjoint_sets()) > 1:
            edge = sample(all_edges, k=1)[0]
            v, u = edge[0], edge[1]
            if done.find(v) != done.find(u):
                result.add_edge(v, u)
                done.union(v, u)
            all_edges.remove(edge)

        return result
示例#4
0
    def __call__(self, chromosome, **kwargs):

        GRAPH = self.STPG.graph

        penality = self.penality_function

        vertices = self.vertices_from_chromosome(chromosome)

        # instânciando variáveis e funções auxiliares
        queue = PriorityQueue()
        dones = set()

        # adiciona uma aresta se os vértices extremos da aresta
        # estão contidos no conjunto vertices
        # mantém essas arestas em uma fila de prioridades para
        # formar uma MST baseado no algoritmo de Kruskal
        # (o trabalho de Kapsalis utilizava o algoritmo de Prim)
        for v in vertices:
            dones.add(v)
            for u in GRAPH.adjacent_to(v):
                if (u in vertices) and (u not in dones):
                    weight = GRAPH.weight(v, u)
                    queue.push(weight, (v, u, weight))

        ## Monta a MST baseado no algoritmo de Kruskal
        DS = DisjointSets()
        for v in vertices:
            DS.make_set(v)

        total_cost = 0
        while queue:
            v, u, weight = queue.pop()
            if DS.find(v) != DS.find(u):
                total_cost += weight
                DS.union(v, u)
        # Repare que não construimos a MST mas apenas
        # definimos os conjuntos disjuntos.

        # a quantidade de partições se refere a
        # quantidade de parents distintos temos no conjunto disjunto.
        qtd_partition = len(DS.get_disjoint_sets())

        total_cost += penality(qtd_partition)

        return total_cost, qtd_partition
示例#5
0
    def __call__(self):
        result = UGraph()
        done = DisjointSets()
        edges = [(u, v) for u, v in self.stpg.graph.gen_undirect_edges()]

        shuffle(edges)

        for v in self.stpg.terminals:
            done.make_set(v)

        while edges and len(done.get_disjoint_sets()) > 1:
            edge = edges.pop()
            y, z = edge[0], edge[1]
            if y not in done: done.make_set(y)
            if z not in done: done.make_set(z)
            if done.find(y) != done.find(z):
                result.add(y, z)
                done.union(y, z)

        return result
示例#6
0
    def __call__(self, treegraph: UGraph):

        GRAPH = self.stpg.graph
        disjointset = DisjointSets()
        result = UGraph()

        for v in treegraph.vertices:
            disjointset.make_set(v)

        # remove edge
        edges = [edge for edge in treegraph.gen_undirect_edges()]
        index = randint(0, len(edges))
        for i, edge in enumerate(edges):
            if index != i:
                result.add_edge(*edge)
                disjointset.union(*edge)

        candidates = list()
        components = disjointset.get_disjoint_sets()

        lesser_idx = min(components, key=lambda key: len(components[key]))
        keys = components.keys() - set([lesser_idx])

        # replace edge
        lesser_component = components[lesser_idx]
        for key in keys:
            other_component = components[key]
            for v in lesser_component:
                for w in GRAPH.adjacent_to(v):
                    if w in other_component:
                        candidates.append((v, w))

            shuffle(candidates)
            while candidates:
                v, w = candidates.pop()
                if disjointset.find(v) != disjointset.find(w):
                    result.add_edge(v, w)
                    disjointset.union(v, w)
                    break

        return result
示例#7
0
    def __call__(self, tree):

        GRAPH = self.STPG.graph
        total_cost = 0
        qtd_partition = 0
        DS = DisjointSets()

        for v in tree.vertices:
            DS.make_set(v)

        for v, u in tree.gen_undirect_edges():
            if DS.find(v) == DS.find(u):
                ## trocar isso por um log
                print("FOI IDENTIFICADO UM CICLO EM UMA DAS SOLUÇÕES")
            DS.union(v, u)
            total_cost += GRAPH.weight(v, u)

        qtd_partition = len(DS.get_disjoint_sets())

        if self.apply_penalization:
            total_cost += self.penality(qtd_partition)

        return total_cost, qtd_partition
示例#8
0
def gen_random_kruskal(stpg: SteinerTreeProblem):

    terminals = set(stpg.terminals)
    edges = [(u, v) for u, v in stpg.graph.gen_undirect_edges()]
    shuffle(edges)

    done = DisjointSets()
    for v in terminals:
        done.make_set(v)

    result = EdgeSet()

    while edges and len(done.get_disjoint_sets()) > 1:
        edge = edges.pop()
        y, z = edge[0], edge[1]
        if y not in done: done.make_set(y)
        if z not in done: done.make_set(z)
        if done.find(y) != done.find(z):
            result.add(y, z)
            done.union(y, z)
            terminals.discard(y)
            terminals.discard(z)

    return result