Exemplo n.º 1
0
    def __call__(self, red: UGraph, blue: UGraph):

        f_weight = lambda v, u: self.stpg.graph.weight(v, u)

        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)

        queue = PriorityQueue()
        start = choice(tuple(self.stpg.terminals))

        for u in union_g.adjacent_to(start):
            queue.push(f_weight(start, u), (start, u))

        result = UGraph()
        while queue:
            start, end = queue.pop()
            if end not in result:
                result.add_edge(start, end)
                for w in union_g.adjacent_to(end):
                    queue.push(f_weight(end, w), (end, w))

        return result
Exemplo n.º 2
0
    def __call__(self, red: UGraph, blue: UGraph):
        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)}'

        terminals = self.terminals.copy()
        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)

        done = set()
        result = UGraph()

        v = terminals.pop()
        while terminals:
            done.add(v)
            adjacents = union_g.adjacent_to(v, lazy=False)
            u = sample(adjacents, k=1)[0]
            if u not in done:
                result.add_edge(v, u)
            terminals.discard(u)
            v = u

        return result
Exemplo n.º 3
0
    def __call__(self, red: UGraph, blue: UGraph):
        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)}'

        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)

        terminals = self.terminals.copy()
        done = set()
        result = UGraph()
        candidates_edges = set()

        vi = terminals.pop()
        done.add(vi)
        for u in union_g.adjacent_to(vi):
            candidates_edges.add((vi, u))

        while candidates_edges and terminals:
            edge = sample(candidates_edges, k=1)[0]
            v, w = edge
            if w not in done:
                done.add(w)
                result.add_edge(v, w)
                terminals.discard(w)
                for u in union_g.adjacent_to(w):
                    if u not in done:
                        candidates_edges.add((w, u))
            candidates_edges.discard((v, w))

        return result
Exemplo n.º 4
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
Exemplo n.º 5
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
    def __call__(self, red: UGraph, blue: UGraph):

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

        p_queue = PriorityQueue()
        vertices = list(g_union.vertices)
        v = choice(vertices)
        for u in g_union.adjacent_to(v):
            weight = self.f_weight(v, u)
            p_queue.push(weight, (v, u))

        g_child = UGraph()
        done = set()
        done.add(v)
        while len(p_queue):
            v, u = p_queue.pop()
            if u not in done:
                g_child.add_edge(v, u)
                done.add(u)

            for w in g_union.adjacent_to(u):
                if w not in done:
                    p_queue.push(self.f_weight(u, w), (u, w))

        terminals = self.STPG.terminals

        prunne_leaves = deque([
            v for v in g_child.vertices
            if ((g_child.degree(v) == 1) and (v not in terminals))
        ])

        while prunne_leaves:
            v = prunne_leaves.pop()
            prev = g_child.adjacent_to(v, lazy=False)
            g_child.remove_node(v)
            for w in prev:
                if g_child.degree(w) == 1 and w not in terminals:
                    prunne_leaves.appendleft(w)

        return g_child
Exemplo n.º 7
0
    def __call__(self, treegraph: UGraph):

        terminals = self.terminals
        result = UGraph()
        for v, u in treegraph.gen_undirect_edges():
            result.add_edge(v, u)

        leaves = deque([
            v for v in result.vertices
            if (v not in terminals) and (result.degree(v) == 1)
        ])

        while leaves:
            v = leaves.pop()
            for w in result.adjacent_to(v):
                if (w not in terminals) and (result.degree(w) == 2):
                    leaves.appendleft(w)
            result.remove_node(v)

        return result
Exemplo n.º 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
Exemplo n.º 9
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