示例#1
0
    def __call__(self, chromosome, **kwargs):
        '''
        Parameters:
            chromosome : is a EdgeSet type or a Bag

        Results :
            _cost : Number
                the edgeset cost
            nro_components : int
                graph components identified
        '''
        assert isinstance(
            chromosome, EdgeSet
        ), f"unsupported operation for chromosome type {type(chromosome)}"

        disjointset = DisjointSets()
        _cost = 0
        GRAPH = self.STPG.graph

        for v, u in chromosome:
            if not GRAPH.has_edge(v, u):
                raise RuntimeError("STPG instance has not this edge")
            _cost += GRAPH.weight(v, u)
            if v not in disjointset:
                disjointset.make_set(v)
            if u not in disjointset:
                disjointset.make_set(u)
            disjointset.union(v, u)

        nro_components = len(disjointset.get_disjoint_sets())

        _cost += self.penality_function(nro_components)

        return _cost, nro_components
示例#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 test_EvaluateZeroChromossome(self):
        stpg = self.stpg
        graph = self.stpg.graph
        nro_terminals = stpg.nro_terminals
        terminals = stpg.terminals

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

        edges_sum = 0
        done = set()
        for t in terminals:
            done.add(t)
            for v in graph.adjacent_to(t):
                if v in terminals and v not in done:
                    disset.union(t, v)
                    edges_sum += graph.weight(t, v)

        qtd_disjoint_sets = len(disset.get_disjoint_sets())

        expected_lenght = stpg.nro_nodes - stpg.nro_terminals
        chromosome = '0' * expected_lenght

        evaluator = EvaluateKruskalBased(stpg)

        evaluator_cost, qtd_partitions = evaluator(chromosome)

        self.assertEqual(evaluator_cost,
                         ((qtd_partitions - 1) * 1_000) + edges_sum)
        self.assertEqual(evaluator_cost,
                         ((qtd_disjoint_sets - 1) * 1_000) + edges_sum)
        self.assertEqual(qtd_partitions, qtd_disjoint_sets)
示例#4
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
示例#5
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
    def test_inserting_item(self):

        DS = DisjointSets()

        for item in range(3, 50, 10):
            DS.make_set(item)

        self.assertEqual(len(DS), 5)
        self.assertEqual(len(DS), len(DS.get_disjoint_sets()))

        with self.assertRaises(ValueError):
            DS.make_set(13)
        ## check ignore_previous
        self.assertTrue(33 in DS)
        DS.make_set(33, ignore_previous=True)

        self.assertTrue(not 171 in DS)
        self.assertFalse(171 in DS)
示例#7
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
示例#8
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
示例#9
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
示例#10
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