コード例 #1
0
    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
コード例 #2
0
    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