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
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
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
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 __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
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
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
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