def __call__(self, red: UGraph, blue: UGraph): child = UGraph() red_only = UGraph() blue_only = UGraph() for v, u in red.gen_undirect_edges(): if blue.has_edge(v, u): child.add_edge(v, u) else: red_only.add_edge(v, u) for v, u in blue.gen_undirect_edges(): if not red.has_edge(v, u): blue_only.add_edge(v, u) common_nodes_red = set(red_only.vertices) & set(blue.vertices) common_nodes_blue = set(blue_only.vertices) & set(red.vertices) red_partitions = self.find_partitions(red_only, common_nodes_red) blue_partitions = self.find_partitions(blue_only, common_nodes_blue) queue = PriorityQueue() for partition in red_partitions: queue.push(partition.cost, partition) for partition in blue_partitions: queue.push(partition.cost, partition) common_nodes = set(red.vertices) | set(blue.vertices) dset = DisjointSets() for v in common_nodes: dset.make_set(v) for v, u in child.gen_undirect_edges(): dset.union(v, u) while queue: partition = queue.pop() if check_portals(partition.portal, dset): # add edges for v, u in partition: child.add_edge(v, u) # update dset portals = iter(partition.portal) p_last = next(portals) for p in portals: dset.union(p_last, p) p_last = p return child
def __call__(self, red: UGraph, blue: UGraph): child = UGraph() red_only = UGraph() blue_only = UGraph() _vertices = set() for v, u in red.gen_undirect_edges(): if blue.has_edge(v, u): child.add_edge(v, u) _vertices.add(v) _vertices.add(u) else: red_only.add_edge(v, u) for v, u in blue.gen_undirect_edges(): if not red.has_edge(v, u): blue_only.add_edge(v, u) common_nodes_red = set(red_only.vertices) & set(blue.vertices) common_nodes_blue = set(blue_only.vertices) & set(red.vertices) red_partitions = self.find_partitions(red_only, common_nodes_red) blue_partitions = self.find_partitions(blue_only, common_nodes_blue) _vertices.update(common_nodes_red | common_nodes_blue) disjoint = DisjointSets() for v in _vertices: disjoint.make_set(v) for v, u in child.gen_undirect_edges(): disjoint.union(v, u) red_dict = _dict_matches_from(red_partitions, disjoint) blue_dict = _dict_matches_from(blue_partitions, disjoint) matches = red_dict.keys() & blue_dict.keys() while matches: child, red_dict, blue_dict, disjoint = select_partition_and_union( child, red_dict, blue_dict, disjoint, matches) red_dict = _dict_matches_from(red_dict.values(), disjoint) blue_dict = _dict_matches_from(blue_dict.values(), disjoint) matches = red_dict.keys() & blue_dict.keys() red_child = UGraph() blue_child = UGraph() for v, u in child.gen_undirect_edges(): red_child.add_edge(v, u) blue_child.add_edge(v, u) for partition in red_dict.values(): for v, u in partition: red_child.add_edge(v, u) for partition in blue_dict.values(): for v, u in partition: blue_child.add_edge(v, u) return red_child, blue_child