Ejemplo n.º 1
0
    def remove_rigid(self):
        """
        Remove rigid links by merging the nodes in place
        """
        while True:
            for i, j, key, edge in self.edges(data=True, keys=True):
                # Can't handle duplicate springs
                if edge["object"] == "rigid":
                    if self.number_of_edges(i, j) != 1:
                        raise RuntimeError(
                            "Cannot have a rigid link across a spring!")
                    bci = "bc" in self.nodes[i]
                    bcj = "bc" in self.nodes[j]
                    if bci and bcj:
                        raise RuntimeError("Cannot merge two nodes with BCs!")
                    self.remove_edge(i, j, key=key)

                    if i < j:
                        if bcj:
                            raise RuntimeError("Internal error: deleting BC")
                        self.replace(nx.contracted_nodes(self, i, j))
                    else:
                        if bci:
                            raise RuntimeError("Internal error: deleting BC")
                        self.replace(nx.contracted_nodes(self, j, i))
                    break
            else:
                break
Ejemplo n.º 2
0
def fast_reg_network_unification(graph, index_syn):
    H = graph.copy()
    cpt = 0
    nodes_size = len(H.nodes())
    for n in H.nodes():
        #print('for each ' + str(n))
        for m in H.nodes():
            if n not in m:
                #print('\tfor each ' + str(m))
                if (fast_are_synonyms(n, m, index_syn=index_syn)):
                    key = index_syn[n]
                    if n not in key:
                        #print('\t\t' + str(n) + ' is synonym with ' + str(m))
                        logging.info('\t\t' + 'merging node ' + str(n) +
                                     ' into node ' + str(key))
                        try:
                            H = nx.contracted_nodes(H, key, n)
                        except:
                            continue
                    if m not in key:
                        logging.info('\t\t' + 'merging node ' + str(m) +
                                     ' into node ' + str(key))
                        try:
                            H = nx.contracted_nodes(H, key, m)
                        except:
                            continue
    return H
Ejemplo n.º 3
0
def old_optimal_centrality(G,S,Q,drop_val):
    '''
    Exact calculation of supernode total distance
    '''
    starttime = timeit.default_timer()
    S = tuple(set(S))
    if len(S)==1:
        superG = G
    else:
        superG = nx.contracted_nodes(G,S[0],S[1],self_loops = False)
    for s in S[2:]:
        superG = nx.contracted_nodes(superG,S[0],s,self_loops=False)
    nx.set_node_attributes(superG,False,'seen')      
    q = [S[0]]
    nx.set_node_attributes(superG,{S[0]:True},'seen')
    nx.set_node_attributes(superG,{S[0]:0},'level')
    centrality = 0
    while q:         
        curr = q.pop(0)
        y = superG.nodes[curr]['level']
        for n in superG.neighbors(curr):
            if superG.nodes()[n]['seen']==False:
                q.append(n)
                centrality += y+1
                if centrality>=drop_val:
                    return drop_val,timeit.default_timer()-starttime 
                nx.set_node_attributes(superG,{n:True},'seen')
                nx.set_node_attributes(superG,{n:y+1},'level')
    Q.add_task(S+(2,),centrality)
    return centrality,timeit.default_timer()-starttime
Ejemplo n.º 4
0
def squeeze_out_edges(fsa, node_to_order):
    # checking each node
    for n in fsa.nodes():
        # checking in edges
        outs = fsa.out_edges(n, data=True)
        word_to_node = defaultdict(set)
        for (_, x, data) in outs:
            if data['attr_dict']['text'] != '':
                word_to_node[data['attr_dict']['text']].add(x)
        for word, to_merge in word_to_node.items():
            if len(to_merge) <= 1:
                continue
            a = list(to_merge)[0]
            b = list(to_merge)[1]
            if node_to_order[a] > node_to_order[b]:
                (a, b) = (b, a)
            if nx.has_path(fsa, a, b):
                # split is required
                new_node = max([k for k in node_to_order]) + 1
                fsa.add_node(new_node)
                fsa.add_edge(new_node, b, key='', attr_dict={'text': ''})
                fsa.remove_edge(n, b, key=word)
                fsa.add_edge(n, new_node, key=word, attr_dict={'text': word})
                fsa = nx.contracted_nodes(fsa, a, new_node)
                clean_up_keys(fsa)
            else:
                # split is required
                # removing the duplicate edge
                fsa.remove_edge(n, b, key=word)
                fsa = nx.contracted_nodes(fsa, a, b)
                clean_up_keys(fsa)
            return True, fsa
    return False, fsa
Ejemplo n.º 5
0
def graph_theory_init(contours):
	global G
	for contour in contours:
		outline = ttfquery.glyph.decomposeOutline(contour, steps=5)
		outline = round_all(outline)
		# # char A is a bit special... need to get rid of duplicate points in contours
		if char == "A" or char == "P" or char == "p" or char == "q":
			outline = sorted(set(outline),key=outline.index)
		outline_str = [str(x) for x in outline]
		# set up the undirected graph with coordinates of outline points as nodes
		# if the two points on the contour is connected, an edge is added
		for i in range(len(outline)-1):
			G.add_node(outline_str[i])
			G.add_edge(outline_str[i],outline_str[i+1])
	if char == "d":
		G = nx.contracted_nodes(G,str((38,29)),str((38,28)))
	if char == "p":
		G = nx.contracted_nodes(G,str((308,28)),str((308,29)))
	if char == "h":
		G.add_edge(str((0,0)),str((0,690)))
		G.remove_edge(str((0,0)),str((0,433)))
	if char == "m" or char == "n" or char == "r":
		G.remove_edge(str((0,0)),str((0,433)))
		G.add_edge(str((0,0)),str((0,510)))
	if char == "y":
		G.remove_edge(str((346,-103)),str((346,77)))
	# get rid of the self loops: nodes connected to itself
	G.remove_edges_from(G.selfloop_edges())
def constructMetaTree(G, l_I):
    metaTree_dict = {}
    index = 0
    # Searching path of type (R, R_V, R') and collapsing them
    while index < len(l_I):
        if l_I[index] not in metaTree_dict:
            metaTree_dict[l_I[index]] = l_I[index]
        visited = {item: False for item in G.nodes}
        tempt, find = DFS_metaTree_len2(G, [], visited, l_I[index])
        if find:
            metaTree_dict[tempt[2]] = tempt[0]
            G.nodes[tempt[0]]['size'] += G.nodes[tempt[2]]['size']
            G = nx.contracted_nodes(G, tempt[0], tempt[2], self_loops=False)
            l_I.remove(tempt[2])
        else:
            index += 1

    # Searching cycles and collapsing them
    index = 0
    while index < len(l_I):
        if l_I[index] not in metaTree_dict:
            metaTree_dict[l_I[index]] = l_I[index]
        tempt = []
        visited = {item: False for item in G.nodes}
        [tempt, aux] = DFS_metaTree_cycle(G, tempt, visited, l_I[index],
                                          l_I[index], 0)
        if aux:
            for i in range(1, len(tempt)):
                if tempt[i] in l_I:
                    metaTree_dict[tempt[i]] = tempt[0]
                    G.nodes[tempt[0]]['size'] += G.nodes[tempt[i]]['size']
                    G = nx.contracted_nodes(G,
                                            tempt[0],
                                            tempt[i],
                                            self_loops=False)
                    l_I.remove(tempt[i])
        else:
            index += 1

    # Collapsing vulnerable leaves to its neighbor
    leaf = [
        x for x in G.nodes
        if G.degree[x] == 1 and not G.nodes[x]['immunization']
    ]
    for item in leaf:
        metaTree_dict[item] = next(G.neighbors(item))
        G.nodes[next(G.neighbors(item))]['size'] += G.nodes[item]['size']
        G = nx.contracted_nodes(G,
                                next(G.neighbors(item)),
                                item,
                                self_loops=False)

    target_nodes = [
        item for item in G.nodes() if not G.nodes[item]['immunization']
    ]
    for item in target_nodes:
        metaTree_dict[item] = item

    return G, metaTree_dict
Ejemplo n.º 7
0
def contractWarriorZombieDragonPlantRockPyroUsableBeast(G):
    H = nx.contracted_nodes(G, "[Warrior]", "[Zombie]", self_loops=False)
    H = nx.contracted_nodes(H, "[Warrior]", "[Dragon]", self_loops=False)
    H = nx.contracted_nodes(H, "[Warrior]", "[Plant]", self_loops=False)
    H = nx.contracted_nodes(H, "[Warrior]", "[Rock]", self_loops=False)
    H = nx.contracted_nodes(H, "[Warrior]", "[Pyro]", self_loops=False)
    # H = nx.contracted_nodes(H, "[Warrior]", "[UsableBeast]", self_loops=False)
    return H
    def merge_nodes(self, node_id: str, other_graph, merge_properties=None):
        """
        Merge two nodes of the same id belonging to two graphs. Optionally
        specify merging behavior for individual properties. Common relationships are merged.
        Example merge properties in Python:
        {
            "name":'discard', # keep property of the caller (also if not mentioned in merged_properties)
            "age":'overwrite', # keep property of the other graph
            "kids":'combine', # make a list of properties
        }
        :param node_id:
        :param other_graph: other graph object
        :param merge_properties:
        :return:
        """
        assert node_id is not None
        assert other_graph is not None
        assert other_graph.graph_exists()

        # find out internal IDs of the two nodes in our graph and other graph
        real_node = self._find_node(node_id=node_id)
        real_other_node = self._find_node(node_id=node_id,
                                          graph_id=other_graph.graph_id)

        # save properties of both (by copy)
        node_props = self.storage.get_graph(
            self.graph_id).nodes[real_node].copy()
        other_props = self.storage.get_graph(
            other_graph.graph_id).nodes[real_other_node].copy()

        # remember that graphid is ignored in get_graph in this implementation, but respected
        # in the disjoint implementation

        # merge the nodes in situ
        nx.contracted_nodes(self.storage.get_graph(self.graph_id),
                            real_node,
                            real_other_node,
                            copy=False)

        # deal with properties
        # remove all properties, including 'contracted' new property
        self.storage.get_graph(self.graph_id).nodes[real_node].clear()

        # construct a new set of properties
        new_props = dict()
        if merge_properties is None:
            new_props = node_props
        else:
            for k, v in node_props.items():
                if k in merge_properties:
                    new_props[k] = node_props[k] if merge_properties[k] == 'discard' else \
                        other_props[k] if merge_properties[k] == 'overwrite' else \
                            [node_props[k], other_props[k]] if merge_properties[k] == 'combine' else None
                else:
                    new_props[k] = node_props[k]
        self.storage.get_graph(
            self.graph_id).nodes[real_node].update(new_props)
Ejemplo n.º 9
0
 def contract_nodes(self, dst, src_list=[]):
     """
     @brief Delete all nodes in 'src_list' and connect all the edges
            that were connected to them to the node 'dst'.
     @returns nothing.
     """
     for v in src_list:
         nx.contracted_nodes(self, dst, v, copy=False)
         # Sometimes nx creates unnecessary self loops...
         if dst in self.adj[dst]:
             self.remove_edge(dst, dst)
def constructMetaTree(G, l_I):
    metaTree_dict = {}
    index = 0

    while index < len(l_I):
        if l_I[index] not in metaTree_dict:
            metaTree_dict[l_I[index]] = l_I[index]
        visited = {item: False for item in G.nodes}
        tempt, find = DFS_metaTree_len2(G, [], visited, l_I[index])
        if find:
            metaTree_dict[tempt[2]] = tempt[0]
            G.nodes[tempt[0]]['size'] += G.nodes[tempt[2]]['size']
            G = nx.contracted_nodes(G, tempt[0], tempt[2], self_loops=False)
            l_I.remove(tempt[2])
        else:
            index += 1

    index = 0
    while index < len(l_I):
        if l_I[index] not in metaTree_dict:
            metaTree_dict[l_I[index]] = l_I[index]
        tempt = []
        visited = {item: False for item in G.nodes}
        [tempt, aux] = DFS_metaTree_cycle(G, tempt, visited, l_I[index],
                                          l_I[index], 0)
        if aux:
            for i in range(1, len(tempt)):
                if tempt[i] in l_I:
                    metaTree_dict[tempt[i]] = tempt[0]
                    G.nodes[tempt[0]]['size'] += G.nodes[tempt[i]]['size']
                    G = nx.contracted_nodes(G,
                                            tempt[0],
                                            tempt[i],
                                            self_loops=False)
                    l_I.remove(tempt[i])
        else:
            index += 1

    leaf = [
        x for x in G.nodes
        if G.degree[x] == 1 and not G.nodes[x]['immunization']
    ]
    for item in leaf:
        metaTree_dict[item] = next(G.neighbors(item))
        G.nodes[next(G.neighbors(item))]['size'] += G.nodes[item]['size']
        G = nx.contracted_nodes(G,
                                next(G.neighbors(item)),
                                item,
                                self_loops=False)

    return G, metaTree_dict
Ejemplo n.º 11
0
 def test_contract_selfloop_graph(self):
     """Tests for node contraction when nodes have selfloops."""
     G = nx.cycle_graph(4)
     G.add_edge(0, 0)
     actual = nx.contracted_nodes(G, 0, 1)
     expected = nx.complete_graph([0, 2, 3])
     expected.add_edge(0, 0)
     expected.add_edge(0, 0)
     assert_edges_equal(actual.edges, expected.edges)
     actual = nx.contracted_nodes(G, 1, 0)
     expected = nx.complete_graph([1, 2, 3])
     expected.add_edge(1, 1)
     expected.add_edge(1, 1)
     assert_edges_equal(actual.edges, expected.edges)
Ejemplo n.º 12
0
    def construct(self):

        A = np.random.randn(30, 60)
        B = np.random.randn(60, 10)
        factors = {'A': A, 'B': B}
        fg = factor_graph(factors, 'ij,kl->ijkl')

        h = 2
        n = 6
        pos = np.zeros((n, 2))
        pos[:, 0] = (np.arange(n) - n / 2.0 + 0.5) * h
        mnx.map_attr('pos', ['i', 'A', 'j', 'k', 'B', 'l'], pos, fg)

        mng = mnx.ManimGraph(fg, get_fg_node, get_fg_edge_curve)

        self.add(mng)
        self.wait(2)

        fg = combine_variables('j', 'k', fg)

        pos = np.zeros((n - 1, 2))
        pos[:, 0] = (np.arange(n - 1) - (n - 1) / 2.0 + 0.5) * h
        mnx.map_attr('pos', ['i', 'A', 'j', 'B', 'l'], pos, fg)
        self.play(*mnx.transform_graph(mng, fg))

        fg = fg.copy()
        fg.nodes['j']['summed'] = True
        self.play(*mnx.transform_graph(mng, fg))

        c = Ellipse(color=GREEN,
                    fill_color=GREEN,
                    fill_opacity=0.3,
                    width=6.5,
                    height=3.5)
        x, y = fg.nodes['j']['pos']
        c.move_to(x * RIGHT + y * DOWN)
        self.play(FadeIn(c))
        self.wait(2)

        fg = nx.contracted_nodes(fg, 'A', 'j')
        fg = nx.contracted_nodes(fg, 'A', 'B')
        fg.node['A']['pos'] = (x, y)
        fg = nx.relabel_nodes(fg, {'A': 'AB'})
        mng.relabel_id(fg, 'A', 'AB')
        fg.nodes['i']['pos'] = (-2, y)
        fg.nodes['l']['pos'] = (2, y)
        self.play(*mnx.transform_graph(mng, fg),
                  Transform(c, get_fg_node('AB', fg)))

        self.wait(2)
Ejemplo n.º 13
0
 def test_contract_selfloop_graph(self):
     """Tests for node contraction when nodes have selfloops."""
     G = nx.cycle_graph(4)
     G.add_edge(0, 0)
     actual = nx.contracted_nodes(G, 0, 1)
     expected = nx.complete_graph([0, 2, 3])
     expected.add_edge(0, 0)
     expected.add_edge(0, 0)
     assert_edges_equal(actual.edges, expected.edges)
     actual = nx.contracted_nodes(G, 1, 0)
     expected = nx.complete_graph([1, 2, 3])
     expected.add_edge(1, 1)
     expected.add_edge(1, 1)
     assert_edges_equal(actual.edges, expected.edges)
def merge_two_trees(tree_pair1: (nx.Graph, int), tree_pair2: (nx.Graph, int),
                    path: list, main_graph: nx.Graph) -> (nx.Graph, int):
    """
    Merge the given two trees into one tree by using the given path between the two trees. The merged tree is returned.
    Note that the nodes of the two trees are contracted into one node in the main_graph. This is done to facilitate
    calculating the min cost paths between other trees in the future.

    :param tree_pair1: the first tree to merge, consisting of the tree graph and the terminal it represents
    :param tree_pair2: the second tree to merge, consisting of the tree graph and the terminal it represents
    :param path: the path from tree1 to tree2 through which the trees are to be merged
    :param main_graph: the underlying graph (containing both trees) is used to obtain node costs
    :return: the tree resulting when merging tree1 with tree2 via the given path, and the terminal it represents
    """
    costs = nx.get_node_attributes(main_graph, 'cost')
    tree1 = tree_pair1[0]
    tree2 = tree_pair2[0]
    # draw_trees_to_merge(tree1, tree2, path, main_graph)
    # first add the path to tree1
    prev_node = -1
    union_edge = None  # this is the edge that joins the connecting path with tree2
    for node in path:
        if tree2.has_node(node):
            union_edge = (prev_node, node)
            break  # the nodes of tree2 will be added when applying the union of the two trees
        if not tree1.has_node(node):
            tree1.add_node(node, cost=costs[node])
            if prev_node >= 0:
                if not tree1.has_edge(prev_node, node):
                    tree1.add_edge(prev_node, node)
                    # contract the newly added nodes in the tree
                    main_graph = nx.contracted_nodes(main_graph,
                                                     prev_node,
                                                     node,
                                                     self_loops=False)
        prev_node = node
    # contract all nodes of tree2 in the main graph
    for node in tree2.nodes():
        main_graph = nx.contracted_nodes(main_graph,
                                         prev_node,
                                         node,
                                         self_loops=False)
        prev_node = node
    # join tree1 with tree2 (which should be disjoint, and connected with "union_edge")
    # draw_trees_to_merge(tree1, tree2, path, main_graph) # DEBUG
    merged_tree = nx.union(tree1, tree2)
    merged_tree.add_edge(union_edge[0], union_edge[1])
    # draw_merged_tree(merged_tree, main_graph) # DEBUG
    # associate the merged tree with the terminal of the first tree
    return merged_tree, tree_pair1[1]
Ejemplo n.º 15
0
def merge_nodes(G,nodes, new_node, attr):
    G_ = G
    for i in range(1, len(nodes)):
        G_ = nx.contracted_nodes(G_, nodes[0], nodes[i], self_loops=False)  # Only works for two nodes at a time apparently
    G__ = nx.relabel.relabel_nodes(G_, {nodes[0] : new_node})
    G__.nodes[new_node].update(attr)
    return G__
def collapse_graph(G, max_T):
    collapse_dict = {}
    collapseCC = []
    Immunized = []
    visited = [False] * G.number_of_nodes()
    for node in G:
        if not visited[node]:
            tempt = []
            collapseCC.append(
                DFS_collapse(G, tempt, visited, node,
                             G.nodes[node]['immunization']))
    for item in collapseCC:
        collapse_dict[item[0]] = item[0]
        # We check if the collapsing set is targeted or not.
        if not G.nodes[item[0]]['immunization']:
            if len(item) == max_T:
                G.nodes[item[0]]['target'] = True
            else:
                G.nodes[item[0]]['target'] = False
        else:
            Immunized.append(item[0])

        G.nodes[item[0]]['size'] = 1
        # We collapse the set of nodes
        if len(item) > 1:
            for index in range(1, len(item)):
                collapse_dict[item[index]] = item[0]
                G.nodes[item[0]]['size'] += 1
                # collapse(G, item[0], item[index], collapse_dict)
                G = nx.contracted_nodes(G,
                                        item[0],
                                        item[index],
                                        self_loops=False)
    return G, Immunized, collapse_dict
Ejemplo n.º 17
0
def simplify_net(network, netx_inp=False):
    netx = network.network_plot if not netx_inp else network
    degrees = degree(netx)

    while True:
        action = False
        affected_nodes = set()
        cliques = sorted(find_cliques(netx),
                         key=lambda c: len(c),
                         reverse=True)

        if len(cliques) <= 1:  # If no more cliques, break
            break

        # For each clique
        for i, clique in enumerate(cliques):
            clean_clique = check_nodes(affected_nodes, clique)

            if not clean_clique:  # If not clean, pass
                continue

            # Contract nodes
            action = True
            base = clique[0]
            affected_nodes.add(base)
            for j in range(1, len(clique)):
                netx = contracted_nodes(netx, base, clique[j])
                affected_nodes.add(clique[j])

        if not action:  # If not action in the last pass, done
            break

    return netx
Ejemplo n.º 18
0
    def remove_duplicate_locations(self):
        """Combine fixed nodes that have the same location."""
        fixed = [n for n, d in self.graph.nodes().items() if d["fixed"] is True]
        combine = {}
        for base_node in fixed:
            combine[base_node] = []
            for other_node in fixed:
                if (
                    self.graph.nodes[base_node]["lon"]
                    == self.graph.nodes[other_node]["lon"]
                    and self.graph.nodes[base_node]["lat"]
                    == self.graph.nodes[other_node]["lat"]
                ):
                    combine[base_node].append(other_node)

        for base_node, combine_list in combine.items():
            for combine_node in combine_list:
                try:
                    lon = self.graph.nodes[base_node]["lon"]
                    lat = self.graph.nodes[base_node]["lat"]
                    self.graph = nx.contracted_nodes(
                        self.graph, base_node, combine_node, self_loops=False
                    )
                    self.graph.nodes[base_node]["fixed"] = True
                    self.graph.nodes[base_node]["lon"] = lon
                    self.graph.nodes[base_node]["lat"] = lat
                except Exception as e:
                    self.log.debug("Already passed {}".format(e))
        self.log.info(
            "Nodes remaining after 'remove_duplicate_locations': {}".format(
                len(self.graph.nodes)
            )
        )
Ejemplo n.º 19
0
 def merge(self, node_pair):
     # node_pair: node_new, node
     # merge node
     self.data.edge_index[self.data.edge_index == node_pair[0]] = node_pair[1]
     node_pair = node_pair.cpu().numpy()
     self.graph = nx.contracted_nodes(self.graph, node_pair[1], node_pair[0])
     self.node_par2s.remove(node_pair[0])
Ejemplo n.º 20
0
def network2nx(x: Union[pd.DataFrame, Iterable],
               threshold: int = 1,
               group_by: Union[dict, None] = None) -> nx.DiGraph:
    """Generates NetworkX graph for neuron connectivity.

    Parameters
    ----------
    x :                 pandas.DataFrame
                        Connectivity information:

                         1. List of edges (columns: 'source', 'target', 'weight')
                         2. Adjacency matrix (pd.DataFrame, rows=sources,
                            columns=targets)

    threshold :         int, optional
                        Connections weaker than this will be excluded.
    group_by :          None | dict, optional
                        Provide a dictionary ``{group_name: [skid1, skid2, ...]}``
                        to collapse sets of nodes into groups.

    Returns
    -------
    networkx.DiGraph
                        NetworkX representation of the network.

    """

    if isinstance(x, pd.DataFrame):
        miss = [c not in x.columns for c in ['source', 'target', 'weight']]
        if all(miss):
            edges = x[['source', 'target', 'weight']].values
        else:
            edges = x.reset_index(inplace=False,
                                  drop=False).melt(id_vars='index',
                                                   inplace=False).values
    elif isinstance(x, (list, np.ndarray)):
        if any([len(e) != 3 for e in x]):
            raise ValueError('Edges must be [source, target, weight]')
        edges = x

    edges = np.array(edges)

    if threshold:
        edges = edges[edges[:, 2] >= threshold]

    # Generate graph and assign custom properties
    g = nx.DiGraph()
    g.add_weighted_edges_from(edges)

    # Group nodes
    if group_by:
        for n, skids in group_by.items():
            # First collapse all nodes into the first of each group
            for s in skids[1:]:
                g = nx.contracted_nodes(g, str(skids[0]), str(s))
            # Now relabel the first node
            g = nx.relabel_nodes(g, {str(skids[0]): str(n)})
            g.nodes[str(n)]['neuron_name'] = str(n)

    return g
Ejemplo n.º 21
0
    def test_edge_attributes(self):
        """Tests that node contraction preserves edge attributes."""
        # Shape: src1 --> dest <-- src2
        G = nx.DiGraph([("src1", "dest"), ("src2", "dest")])
        G["src1"]["dest"]["value"] = "src1-->dest"
        G["src2"]["dest"]["value"] = "src2-->dest"
        H = nx.MultiDiGraph(G)

        G = nx.contracted_nodes(G, "src1", "src2")  # New Shape: src1 --> dest
        assert G.edges[("src1", "dest")]["value"] == "src1-->dest"
        assert (G.edges[("src1", "dest")]["contraction"][(
            "src2", "dest")]["value"] == "src2-->dest")

        H = nx.contracted_nodes(H, "src1",
                                "src2")  # New Shape: src1 -(x2)-> dest
        assert len(H.edges(("src1", "dest"))) == 2
Ejemplo n.º 22
0
def make_acyclic_3(funct_g_2):
    
    G_REDUCED_2 = funct_g_2.copy()
    Super_nodes = {}
    for i in range(len(G_REDUCED_2.nodes())):
        Super_nodes[i] = [i]

    A_Cycle = []
    try:
        A_Cycle = nx.find_cycle(G_REDUCED_2, orientation='original')
#         print(A_Cycle)
    except:
        pass

    while A_Cycle !=[]:
        for i in range(len(A_Cycle)-1):
#             print('i: '+str(i))
    #         print(A_Cycle)
            if (A_Cycle[0][0], A_Cycle[i+1][0]) in G_REDUCED_2.edges():
                G_REDUCED_2 = nx.contracted_nodes(G_REDUCED_2, A_Cycle[0][0], A_Cycle[i+1][0], self_loops=False)
                Super_nodes[A_Cycle[0][0]].extend(Super_nodes[A_Cycle[i+1][0]])
                Super_nodes[A_Cycle[0][0]] = list(set(Super_nodes[A_Cycle[0][0]]))
                del Super_nodes[A_Cycle[i+1][0]]
            else:
    #             break
                A_Cycle = []
    #     A_Cycle = nx.find_cycle(G_REDUCED_2, orientation='original')
        try:
            A_Cycle = nx.find_cycle(G_REDUCED_2, orientation='original')
#             print(A_Cycle)
        except:
            A_Cycle = []
            pass
        
    return G_REDUCED_2, Super_nodes
Ejemplo n.º 23
0
def make_acyclic(G):
    flag = 0
    G_REDUCED = G.copy()
    Cycles = nx.simple_cycles(G_REDUCED)
    Cycles_list = list(Cycles)
    if Cycles_list != []:
#         print('All cycles are: ' + str(Cycles_list))
        flag = 1
    else:
        print('No cycle found.')
        
    if flag == 1:
        while len(max(Cycles_list,key=len))>1:
            Cycles = nx.simple_cycles(G_REDUCED)
            Cycles_list = list(Cycles)
            bigest_Cycle = max(Cycles_list,key=len)
#             print('Bigest Cycle is: ' + str(bigest_Cycle) + ' with length of ' + str(len(bigest_Cycle)))

            for i in range(len(bigest_Cycle)-1):
                G_REDUCED = nx.contracted_nodes(G_REDUCED, bigest_Cycle[0], bigest_Cycle[i+1], self_loops=True)
#                 print('i = '+str(i))
                b2 = nx.simple_cycles(G_REDUCED)
                b2_list = list(b2)
#                 print('All cycles in g_reduced are: ' + str(b2_list))
                
        for i in range(len(b2_list)):
            G_REDUCED.remove_edge(b2_list[i][0],b2_list[i][0])

    return G_REDUCED
Ejemplo n.º 24
0
def merge_leaf_nodes(graph,
                     head_node=None,
                     quant_active=None,
                     quant_scope=None):
    """
    Traverses the graph, merging those nodes
    with the same label within the same quantificaton scope.
    """
    if head_node is None:
        head_node = graph.graph['head_node']
    # Get nodes and their scope information.
    scoped_nodes = get_scoped_nodes(graph, head_node)
    for (quant_node, expr), nodes_to_merge in scoped_nodes.items():
        if len(nodes_to_merge) > 1:
            master_node, node_type = nodes_to_merge[0]
            assert node_type == 'leaf'
            for node, node_type in nodes_to_merge[1:]:
                # Merge leaves within the same scope:
                if node_type == 'leaf':
                    graph = nx.contracted_nodes(graph, master_node, node)
                # Add edges from quantifier to internal function names:
                elif node_type == 'internal':
                    graph.add_edge(quant_node, node)
    graph.graph['head_node'] = head_node
    return graph
Ejemplo n.º 25
0
    def _combine_nodes_in_linked_entities(self):
        wiki_entities = list()

        for entity_range in self.sentence_entities.keys():

            nodes_to_merge = list()
            for node in self.graph.nodes(data=True):
                if any([each[0] >= entity_range[0] and each[1] <= entity_range[1] for each in node[1]['range']]):
                    nodes_to_merge.append(node)

            wiki_entities.append((self.sentence_entities[entity_range]['uri'], nodes_to_merge))

        assert (len(wiki_entities) == len(self.sentence_entities))

        for (wiki_id, nodes_to_merge_list) in wiki_entities:
            if len(nodes_to_merge_list) > 1:
                for index in range(1, len(nodes_to_merge_list)):
                    self.graph = nx.contracted_nodes(self.graph, nodes_to_merge_list[index][0], nodes_to_merge_list[index - 1][0],
                                            self_loops=False)

                self.graph = nx.relabel.relabel_nodes(self.graph, {nodes_to_merge_list[index][0]: wiki_id})
            elif len(nodes_to_merge_list) == 1:
                self.graph = nx.relabel.relabel_nodes(self.graph, {nodes_to_merge_list[0][0]: wiki_id})

        wiki_attribute = {key: {'surfaceform': self.wiki2surfaceform[key]} for key in self.graph.nodes}
        nx.set_node_attributes(self.graph, wiki_attribute)
Ejemplo n.º 26
0
def arrange_quantifiers(graph):
    """
    Collapse all quantifier instances into nodes attached
    to the root.
    """
    head_node = guess_head_node(graph)
    quant_nodes = [n for n in graph.nodes() if is_quantifier_node(graph, n)]
    for qn in quant_nodes:
        # from pudb import set_trace; set_trace()
        pred_not_quant = find_predecessor_not_quant(graph, qn)
        term_node = get_term_node_from_quant(graph, qn)
        graph.add_edge(pred_not_quant, term_node)
        graph.remove_edge(qn, term_node)

        for pred in list(graph.predecessors(qn)):
            graph.remove_edge(pred, qn)
        graph.add_edge(head_node, qn)

    q_dict = defaultdict(list)
    for qn in quant_nodes:
        q_dict[get_label(graph, qn)].append(qn)
    for qn_type, nodes in q_dict.items():
        if len(nodes) > 1:
            master_quant_node = nodes[0]
            for qn in nodes[1:]:
                graph = nx.contracted_nodes(graph, master_quant_node, qn)
    return graph
Ejemplo n.º 27
0
 def test_undirected_node_contraction(self):
     """Tests for node contraction in an undirected graph."""
     G = nx.cycle_graph(4)
     actual = nx.contracted_nodes(G, 0, 1)
     expected = nx.cycle_graph(3)
     expected.add_edge(0, 0)
     assert nx.is_isomorphic(actual, expected)
Ejemplo n.º 28
0
 def test_undirected_node_contraction(self):
     """Tests for node contraction in an undirected graph."""
     G = nx.cycle_graph(4)
     actual = nx.contracted_nodes(G, 0, 1)
     expected = nx.complete_graph(3)
     expected.add_edge(0, 0)
     assert_true(nx.is_isomorphic(actual, expected))
Ejemplo n.º 29
0
    def merge_two_nodes(self, left_id, right_id):
        """
        remove right node to left node, and right_id will be delete;
        merge SMILES of these two nodes;
        add new fragment to self.f2f;
        update count and frequency in self.f2f
        """
        if self.check_if_merge(left_id, right_id):
            raw_smiles_left = self.g.nodes[left_id]['smiles']
            raw_smiles_right = self.g.nodes[right_id]['smiles']
            g2 = nx.contracted_nodes(self.g, left_id, right_id, self_loops=False)
            merged_result = self._merge_smiles(left_id, right_id)
            merged_smiles = merged_result['merged_smiles']
            g2.nodes[left_id]['smiles'] = merged_smiles
            g2.nodes[left_id]['mol_inx'] = list(merged_result['merged_inx'])
            if self.test:
                print('  >Merged result is: {}'.format(merged_result))
                print('  >New network: {}'.format(g2.nodes(data=True)))

            if merged_smiles not in self.f2f.index:
                self.f2f.loc[merged_smiles, 'count'] = 0
            self.f2f.loc[merged_smiles, 'count'] += 1
            self.f2f.loc[raw_smiles_left, 'count'] -= 1
            self.f2f.loc[raw_smiles_right, 'count'] -= 1
            self.f2f['frequency'] = self.f2f['count'] / self.f2f['count'].sum()
            self.g = g2.copy()
Ejemplo n.º 30
0
    def _similarity_merge(self, regions, thr=0.65):
        """
        (Private) Procedure that merge similar segments 

        :param regions:
            The properties of the initially computed regions.
        :param thr:
            The threshold for merging. This value depends on the distance considered. 
        """
        def _findregion(R):
            for i in range(len(regions)):
                if regions[i].label == R:
                    return i

        for u, v in self._merged_RAG.edges():
            Ri = regions[_findregion(u)]
            Rj = regions[_findregion(v)]
            sim = self._merged_RAG[u][v]['weight']
            if sim >= thr:
                max_label = Ri if Ri.label > Rj.label else Rj
                min_label = Ri if Ri.label < Rj.label else Rj
                for (x, y) in max_label.coords:
                    self._segmentation_merged[(x, y)] = min_label.label
                self._merged_RAG = contracted_nodes(self._merged_RAG,
                                                    min_label.label,
                                                    max_label.label,
                                                    self_loops=False)
                return True
        return False
Ejemplo n.º 31
0
    def _pixels_merge(self, regions, thr_pixels=750):
        """
        (Private) Procedure that merge small segments with their closest neighbor.

        :param regions:
            The properties of the initially computed regions.
        :param thr_pixels:
            The threshold size for merging.
        """
        def _findregion(R):
            for i in range(len(regions)):
                if regions[i].label == R:
                    return i

        for i in range(len(regions)):
            Ri = regions[i]
            lenRi = len(Ri.coords)
            if (lenRi < thr_pixels):
                neighbors = list(self._merged_RAG.neighbors(Ri.label))
                closest = max(
                    [(regions[_findregion(Rj)].label, self._merged_RAG[
                        Ri.label][regions[_findregion(Rj)].label]['weight'])
                     for Rj in neighbors],
                    key=lambda x: x[1])[0]
                Rj = regions[_findregion(closest)]
                max_label = Ri if Ri.label > Rj.label else Rj
                min_label = Ri if Ri.label < Rj.label else Rj
                for (x, y) in max_label.coords:
                    self._segmentation_merged[(x, y)] = min_label.label
                self._merged_RAG = contracted_nodes(self._merged_RAG,
                                                    min_label.label,
                                                    max_label.label,
                                                    self_loops=False)
                return True
        return False
Ejemplo n.º 32
0
def clean_game_titles_in_graph(G, to_merge, t_names, g_names):
    for k, v in to_merge.items():
        target_node = None
        source_nodes = []
        for node in v:
            if node in nx.nodes(G):
                if target_node is None:
                    target_node = node
                else:
                    source_nodes.append(node)
        if target_node is not None and len(source_nodes) > 0:
            for source_node in source_nodes:
                G = nx.contracted_nodes(G, target_node, source_node)

                if target_node not in t_names.keys(
                ) and source_node in t_names.keys():
                    t_names[target_node] = t_names[source_node]
                    g_names[target_node] = g_names[source_node]
                    del t_names[source_node]
                    del g_names[source_node]

    total_weight_dict = {}
    for node in G.nodes():
        total_weight = 0.0
        for edge in G.edges(node, data=True):
            total_weight += edge[2]['weight']
        total_weight_dict[node] = total_weight

    nx.set_node_attributes(G, name='total_weight', values=total_weight_dict)

    return G, list(total_weight_dict.values()), t_names, g_names
Ejemplo n.º 33
0
 def test_multigraph_keys(self):
     """Tests that multiedge keys are reset in new graph."""
     G = nx.path_graph(3, create_using=nx.MultiGraph())
     G.add_edge(0, 1, 5)
     G.add_edge(0, 0, 0)
     G.add_edge(0, 2, 5)
     actual = nx.contracted_nodes(G, 0, 2)
     expected = nx.MultiGraph()
     expected.add_edge(0, 1, 0)
     expected.add_edge(0, 1, 5)
     expected.add_edge(0, 1, 2)  # keyed as 2 b/c 2 edges already in G
     expected.add_edge(0, 0, 0)
     expected.add_edge(0, 0, 1)  # this comes from (0, 2, 5)
     assert_edges_equal(actual.edges, expected.edges)
Ejemplo n.º 34
0
 def test_create_multigraph(self):
     """Tests that using a MultiGraph creates multiple edges."""
     G = nx.path_graph(3, create_using=nx.MultiGraph())
     G.add_edge(0, 1)
     G.add_edge(0, 0)
     G.add_edge(0, 2)
     actual = nx.contracted_nodes(G, 0, 2)
     expected = nx.MultiGraph()
     expected.add_edge(0, 1)
     expected.add_edge(0, 1)
     expected.add_edge(0, 1)
     expected.add_edge(0, 0)
     expected.add_edge(0, 0)
     assert_edges_equal(actual.edges, expected.edges)
Ejemplo n.º 35
0
 def test_node_attributes(self):
     """Tests that node contraction preserves node attributes."""
     G = nx.cycle_graph(4)
     # Add some data to the two nodes being contracted.
     G.node[0] = dict(foo='bar')
     G.node[1] = dict(baz='xyzzy')
     actual = nx.contracted_nodes(G, 0, 1)
     # We expect that contracting the nodes 0 and 1 in C_4 yields K_3, but
     # with nodes labeled 0, 2, and 3, and with a self-loop on 0.
     expected = nx.complete_graph(3)
     expected = nx.relabel_nodes(expected, {1: 2, 2: 3})
     expected.add_edge(0, 0)
     expected.node[0] = dict(foo='bar', contraction={1: dict(baz='xyzzy')})
     assert_true(nx.is_isomorphic(actual, expected))
     assert_equal(actual.node, expected.node)
def cleanRedundantNodes(DG, trajectories_data_f):
    while 1:
        #join trajectories that only has as parent and child each other. (A->B->C)
        same_nodes = []
        for ind1 in DG.nodes():
            next_nodes = DG.successors(ind1)
            if len(next_nodes) == 1:
                pp = DG.predecessors(next_nodes[0]);
                if len(pp) == 1 and pp[0] == ind1 and ind1!=next_nodes[0]:
                    same_nodes.append((ind1, next_nodes[0]))
        if len(same_nodes) == 0:
            break
        
        for ind1, ind2 in same_nodes:
            DG = nx.contracted_nodes(DG, ind1, ind2)
            
            row2chg = trajectories_data_f.worm_index_auto == ind2
            trajectories_data_f.loc[row2chg, 'worm_index_auto'] = ind1
    
    
    return DG, trajectories_data_f
Ejemplo n.º 37
0
def edge_function(G,M,Forest,unmarked_edges,tree_to_root,tree_num_of_v,root_of_v,v,Blossom_stack,e):
    e2 = (e[1],e[0]) #the edge in the other order
    if ((e in unmarked_edges or e2 in unmarked_edges) and e!=[]):
        w = e[1] # the other vertex of the unmarked edge
        w_in_Forest = 0; ##Indicator for w in F or not

        ##Go through all the trees in the forest to check if w in F
        tree_of_w = None
        tree_num_of_w = None
        for tree_number in xrange(len(Forest)):
            tree = Forest[tree_number]
            if tree.has_node(w) == True:
                w_in_Forest = 1
                root_of_w = tree_to_root[tree_number]
                tree_num_of_w = tree_number
                tree_of_w = Forest[tree_num_of_w]
                break #Break the outer for loop
        
        if w_in_Forest == 0:
            ## w is matched, so add e and w's matched edge to F
            Forest[tree_num_of_v].add_edge(e[0],e[1]) # edge {v,w} 
            # print "edge added to forest: ", e
            # Note: we don't add w to forest nodes b/c it's odd dist from root
            # assert(M.has_node(w))
            edge_w = list(M.edges(w))[0] # get edge {w,x}
            return (1,edge_w) ## store to add to forest after parallel for

        else: ## w is in Forest
            # if odd, do nothing.
            if dist_to_root(w,root_of_w,Forest[tree_num_of_w])%2 == 1: #CASE 4
                return (4,0) 
            if dist_to_root(w,root_of_w,Forest[tree_num_of_w])%2 == 0:
                if (tree_num_of_v != tree_num_of_w):
                    ##Shortest path from root(v)--->v-->w---->root(w)
                    path_in_v = nx.shortest_path(Forest[tree_num_of_v], source = root_of_v, target = v)
                    path_in_w = nx.shortest_path(Forest[tree_num_of_w], source = w, target = root_of_w)
                    return (2,path_in_v + path_in_w)
                else: ##Contract the blossom
                    # create blossom
                    blossom = nx.shortest_path(tree_of_w, source=v, target=w)
                    blossom.append(v)
                    # assert(len(blossom)%2 == 0)
                    # contract blossom into single node w
                    contracted_G = copy.deepcopy(G)
                    contracted_M = copy.deepcopy(M)
                    for node in blossom[0:len(blossom)-1]:
                        if node != w:
                            contracted_G = nx.contracted_nodes(contracted_G, w, node, self_loops=False)
                            if node in contracted_M.nodes(): 
                               edge_rm = list(M.edges(node))[0] #this will be exactly one edge
                               contracted_M.remove_node(node)
                               contracted_M.remove_node(edge_rm[1])
                               # assert(len(list(contracted_M.nodes()))%2 == 0)
                    # add blossom to our stack
                    Blossom_stack.append(w)

                    # recurse
                    aug_path = finding_aug_path(contracted_G, contracted_M, Blossom_stack)

                    # check if blossom exists in aug_path 
                    v_B = Blossom_stack.pop()
                    if (v_B in aug_path):
                        ##Define the L_stem and R_stem
                        L_stem = aug_path[0:aug_path.index(v_B)]
                        R_stem = aug_path[aug_path.index(v_B)+1:]
                        lifted_blossom = [] #stores the path within the blossom to take

                        # Find base of blossom
                        i = 0
                        base = None
                        base_idx = -1
                        blossom_ext = blossom + [blossom[1]] 
                        while base == None and i < len(blossom) - 1:
                            if not(M.has_edge(blossom[i],blossom[i+1])):
                                if not(M.has_edge(blossom[i+1],blossom_ext[i+2])): 
                                    base = blossom[i+1]
                                    base_idx = i+1
                                else:
                                    i += 2
                            else:
                                i += 1

                        # if needed, create list of blossom nodes starting at base
                        if blossom[0] != base:
                            based_blossom = []
                            base_idx = blossom.index(base)
                            for i in xrange(base_idx,len(blossom)-1):
                                based_blossom.append(blossom[i])
                            for i in xrange(0,base_idx):
                                based_blossom.append(blossom[i])
                            based_blossom.append(base)
                        else:
                            based_blossom = blossom

                        # CHECK IF BLOSSOM IS ENDPT
                        if L_stem == [] or R_stem == []:
                            if L_stem != []:
                                if G.has_edge(base, L_stem[-1]):
                                    # CASE 1:
                                    # Chuck the blossom. 
                                    return L_stem + [base]
                                else:
                                    # CASE 2:
                                    # find where Lstem is connected
                                    i = 1
                                    while (lifted_blossom == []):
                                        # assert(i < len(based_blossom)-1)
                                        if G.has_edge(based_blossom[i],L_stem[-1]):
                                            # make sure we're adding the even part to lifted path
                                            if i%2 == 0: # same dir path
                                                lifted_blossom = list(reversed(based_blossom))[-i-1:]
                                            else: # opposite dir path
                                                lifted_blossom = based_blossom[i:]
                                        i += 1
                                    return (3,L_stem + lifted_blossom)

                            else:
                                if G.has_edge(base, R_stem[0]):
                                    # CASE 1:
                                    # Chuck the blossom. 
                                    return (3,[base] + R_stem)
                                else:
                                    # CASE 2:
                                    # find where R_stem is connected
                                    i = 1
                                    while (lifted_blossom == []):
                                        # assert(i < len(based_blossom)-1)
                                        if G.has_edge(based_blossom[i],R_stem[0]):
                                            # make sure we're adding the even part to lifted path
                                            if i%2 == 0: # same dir path
                                                lifted_blossom = based_blossom[:i+1]
                                                print lifted_blossom
                                            else: # opposite dir path
                                                lifted_blossom = list(reversed(based_blossom))[:-i]
                                        i += 1
                                    return (3,lifted_blossom + R_stem)

                        else: # blossom is in the middle
                            # LIFT the blossom
                            # check if L_stem attaches to base
                            if M.has_edge(base, L_stem[-1]):
                                # find where right stem attaches
                                if G.has_edge(base, R_stem[0]):
                                    # blossom is useless
                                    return (3,L_stem + [base] + R_stem)
                                else:
                                    # blossom needs to be lifted
                                    i = 1
                                    while (lifted_blossom == []):
                                        # assert(i < len(based_blossom)-1)
                                        if G.has_edge(based_blossom[i],R_stem[0]):
                                            # make sure we're adding the even part to lifted path
                                            if i%2 == 0: # same dir path
                                                lifted_blossom = based_blossom[:i+1] 
                                                # print lifted_blossom
                                            else: # opposite dir path
                                                lifted_blossom = list(reversed(based_blossom))[:-i]
                                                # print lifted_blossom
                                        i += 1
                                    return (3,L_stem + lifted_blossom + R_stem)
                            else: 
                                # R stem to base is in matching
                                # assert(M.has_edge(base, R_stem[0]))
                                # check where left stem attaches
                                if G.has_edge(base, L_stem[-1]):
                                    # blossom is useless
                                    return (3,L_stem + [base] + R_stem)
                                else:
                                    # blossom needs to be lifted
                                    i = 1
                                    while (lifted_blossom == []):
                                        # assert(i < len(based_blossom)-1)
                                        if G.has_edge(based_blossom[i],L_stem[-1]):
                                            # make sure we're adding the even part to lifted path
                                            if i%2 == 0: # same dir path
                                                lifted_blossom = list(reversed(based_blossom))[-i-1:] 
                                            else: # opposite dir path
                                                lifted_blossom = based_blossom[i:] 
                                        i += 1
                                    return (3,L_stem + list((lifted_blossom)) + R_stem)

                    else: # blossom is not in aug_path
                        return (3,aug_path)
Ejemplo n.º 38
0
def finding_aug_path(G,M,Blossom_stack=[]):
    Forest = [] #Storing the Forests
    Path = [] # The final path 

    unmarked_edges = list(set(G.edges()) - set(M.edges()))
    unmarked_nodes = list(G.nodes())
    Forest_nodes = []
    ## we need a map from v to the tree
    tree_to_root = {} # key=idx of tree in forest, val=root
    root_to_tree = {} # key=root, val=idx of tree in forest
        
    ##List of exposed vertices - ROOTS OF TREES
    exp_vertex = list(set(G.nodes()) - set(M.nodes()))
    
    counter = 0
    #List of trees with the exposed vertices as the roots
    for v in exp_vertex:  
        temp = nx.Graph()
        temp.add_node(v)
        Forest.append(temp)
        Forest_nodes.append(v)

        #link each root to its tree
        tree_to_root[counter] = v
        root_to_tree[v] = counter
        counter = counter + 1

    
    for v in Forest_nodes:  
        root_of_v = None
        tree_num_of_v = None
        for tree_number in xrange(len(Forest)): 
            tree_in = Forest[tree_number]
            if tree_in.has_node(v) == True:
                root_of_v = tree_to_root[tree_number]
                tree_num_of_v = tree_number
                break #Break out of the for loop
        edges_v = list(G.edges(v))
        for edge_number in xrange(len(edges_v)): 
            e = edges_v[edge_number]
            e2 = (e[1],e[0]) #the edge in the other order
            if ((e in unmarked_edges or e2 in unmarked_edges) and e!=[]):
                w = e[1] # the other vertex of the unmarked edge
                w_in_Forest = 0; ##Indicator for w in F or not

                ##Go through all the trees in the forest to check if w in F
                tree_of_w = None
                tree_num_of_w = None
                for tree_number in xrange(len(Forest)):
                    tree = Forest[tree_number]
                    if tree.has_node(w) == True:
                        w_in_Forest = 1
                        root_of_w = tree_to_root[tree_number]
                        tree_num_of_w = tree_number
                        tree_of_w = Forest[tree_num_of_w]
                        break #Break the outer for loop
                
                if w_in_Forest == 0:
                    ## w is matched, so add e and w's matched edge to F
                    Forest[tree_num_of_v].add_edge(e[0],e[1]) # edge {v,w}
                    # Note: we don't add w to forest nodes b/c it's odd dist from root
                    #assert(M.has_node(w))
                    edge_w = list(M.edges(w))[0] # get edge {w,x}
                    Forest[tree_num_of_v].add_edge(edge_w[0],edge_w[1]) # add edge{w,x}
                    Forest_nodes.append(edge_w[1]) ## add {x} to the list of forest nodes

                else: ## w is in Forest
                    # if odd, do nothing.
                    if dist_to_root(w,root_of_w,Forest[tree_num_of_w])%2 == 0:
                        if (tree_num_of_v != tree_num_of_w):
                            ##Shortest path from root(v)--->v-->w---->root(w)
                            path_in_v = nx.shortest_path(Forest[tree_num_of_v], source = root_of_v, target = v)
                            path_in_w = nx.shortest_path(Forest[tree_num_of_w], source = w, target = root_of_w)

                            return path_in_v + path_in_w
                        else: ##Contract the blossom
                            # create blossom
                            blossom = nx.shortest_path(tree_of_w, source=v, target=w)
                            blossom.append(v)
                            #assert(len(blossom)%2 == 0)
                            # contract blossom into single node w
                            contracted_G = copy.deepcopy(G)
                            contracted_M = copy.deepcopy(M)
                            for node in blossom[0:len(blossom)-1]:
                                if node != w:
                                    contracted_G = nx.contracted_nodes(contracted_G, w, node, self_loops=False)
                                    if node in contracted_M.nodes(): 
                                       edge_rm = list(M.edges(node))[0] #this will be exactly one edge
                                       contracted_M.remove_node(node)
                                       contracted_M.remove_node(edge_rm[1])
                                       #assert(len(list(contracted_M.nodes()))%2 == 0)
                            # add blossom to our stack
                            Blossom_stack.append(w)

                            # recurse
                            aug_path = finding_aug_path(contracted_G, contracted_M, Blossom_stack)

                            # check if blossom exists in aug_path 
                            v_B = Blossom_stack.pop()
                            if (v_B in aug_path):
                                ##Define the L_stem and R_stem
                                L_stem = aug_path[0:aug_path.index(v_B)]
                                R_stem = aug_path[aug_path.index(v_B)+1:]
                                lifted_blossom = [] #stores the path within the blossom to take
                                # Find base of blossom
                                i = 0
                                base = None
                                base_idx = -1
                                blossom_ext = blossom + [blossom[1]] 
                                while base == None and i < len(blossom) - 1:
                                    if not(M.has_edge(blossom[i],blossom[i+1])):
                                        if not(M.has_edge(blossom[i+1],blossom_ext[i+2])): 
                                            base = blossom[i+1]
                                            base_idx = i+1
                                        else:
                                            i += 2
                                    else:
                                        i += 1
                                # if needed, create list of blossom nodes starting at base
                                if blossom[0] != base:
                                    based_blossom = []
                                    base_idx = blossom.index(base)
                                    for i in xrange(base_idx,len(blossom)-1):
                                        based_blossom.append(blossom[i])
                                    for i in xrange(0,base_idx):
                                        based_blossom.append(blossom[i])
                                    based_blossom.append(base)
                                else:
                                    based_blossom = blossom

                                # CHECK IF BLOSSOM IS ENDPT
                                if L_stem == [] or R_stem == []:
                                    if L_stem != []:
                                        if G.has_edge(base, L_stem[-1]):
                                            # CASE 1:
                                            # Chuck the blossom
                                            return L_stem + [base]
                                        else:
                                            # CASE 2:
                                            # find where Lstem is connected
                                            i = 1
                                            while (lifted_blossom == []):
                                                #assert(i < len(based_blossom)-1)
                                                if G.has_edge(based_blossom[i],L_stem[-1]):
                                                    # make sure we're adding the even part to lifted path
                                                    if i%2 == 0: # same dir path
                                                        lifted_blossom = list(reversed(based_blossom))[-i-1:] ####################
                                                    else: # opposite dir path
                                                        lifted_blossom = based_blossom[i:]##########################
                                                i += 1
                                            return L_stem + lifted_blossom

                                    else:
                                        if G.has_edge(base, R_stem[0]):
                                            # CASE 1:
                                            # Chuck the blossom. 
                                            return [base] + R_stem
                                        else:
                                            # CASE 2:
                                            # find where R_stem is connected
                                            i = 1
                                            while (lifted_blossom == []):
                                                #assert(i < len(based_blossom)-1)
                                                if G.has_edge(based_blossom[i],R_stem[0]):
                                                    # make sure we're adding the even part to lifted path
                                                    if i%2 == 0: # same dir path
                                                        lifted_blossom = based_blossom[:i+1]
                                                        #print lifted_blossom
                                                    else: # opposite dir path
                                                        lifted_blossom = list(reversed(based_blossom))[:-i]
                                                i += 1
                                            return lifted_blossom + R_stem

                                else: # blossom is in the middle
                                    # LIFT the blossom
                                    # check if L_stem attaches to base
                                    if M.has_edge(base, L_stem[-1]):
                                        # find where right stem attaches
                                        if G.has_edge(base, R_stem[0]):
                                            # blossom is useless
                                            return L_stem + [base] + R_stem
                                        else:
                                            # blossom needs to be lifted
                                            i = 1
                                            while (lifted_blossom == []):
                                                # assert(i < len(based_blossom)-1)
                                                if G.has_edge(based_blossom[i],R_stem[0]):
                                                    # make sure we're adding the even part to lifted path
                                                    if i%2 == 0: # same dir path
                                                        lifted_blossom = based_blossom[:i+1] 
                                                        # print lifted_blossom
                                                    else: # opposite dir path
                                                        lifted_blossom = list(reversed(based_blossom))[:-i]
                                                        # print lifted_blossom
                                                i += 1
                                            return L_stem + lifted_blossom + R_stem
                                    else: 
                                        # R stem to base is in matching
                                        # assert(M.has_edge(base, R_stem[0]))
                                        # check where left stem attaches
                                        if G.has_edge(base, L_stem[-1]):
                                            # blossom is useless
                                            return L_stem + [base] + R_stem
                                        else:
                                            # blossom needs to be lifted
                                            i = 1
                                            while (lifted_blossom == []):
                                                # assert(i < len(based_blossom)-1)
                                                if G.has_edge(based_blossom[i],L_stem[-1]):
                                                    # make sure we're adding the even part to lifted path
                                                    if i%2 == 0: # same dir path
                                                        lifted_blossom = list(reversed(based_blossom))[-i-1:] 
                                                    else: # opposite dir path
                                                        lifted_blossom = based_blossom[i:] 
                                                i += 1
                                            return L_stem + list((lifted_blossom)) + R_stem
                            else: # blossom is not in aug_path
                                return aug_path
    ##IF Nothing is Found
    return Path ##Empty Path
Ejemplo n.º 39
0
 def test_without_self_loops(self):
     """Tests for node contraction without preserving self-loops."""
     G = nx.cycle_graph(4)
     actual = nx.contracted_nodes(G, 0, 1, self_loops=False)
     expected = nx.complete_graph(3)
     assert_true(nx.is_isomorphic(actual, expected))
Ejemplo n.º 40
0
def finding_aug_path(G,M,Blossom_stack=[]):
    Forest = [] #Storing the Trees
    Path = [] # The final path 

    unmarked_edges = list(set(G.edges()) - set(M.edges()))
    unmarked_nodes = list(G.nodes())
    Forest_nodes = []

    ## we need a map from v to the tree
    tree_to_root = {} # key=idx of tree in forest, val=root
    root_to_tree = {} # key=root, val=idx of tree in forest
        
    ##List of exposed vertices - ROOTS OF TREES
    exp_vertex = list(set(G.nodes()) - set(M.nodes()))
    
    counter = 0
    #List of trees with the exposed vertices as the roots
    for v in exp_vertex:  ######## could be parallelized
        temp = nx.Graph()
        temp.add_node(v)
        Forest.append(temp)
        Forest_nodes.append(v)

        #link each root to its tree
        tree_to_root[counter] = v
        root_to_tree[v] = counter
        counter = counter + 1

    
    for v in Forest_nodes:  
        root_of_v = None
        tree_num_of_v = None
        for tree_number in xrange(len(Forest)): ######## could be parallelized
            # find tree of v
            tree_in = Forest[tree_number]
            if tree_in.has_node(v) == True:
                root_of_v = tree_to_root[tree_number]
                tree_num_of_v = tree_number
                break #Break out of the for loop
        edges_v = list(G.edges(v))
        pool = Pool(processes = 4)
        edge_data = edges_v
        # Feed the function all global args
        partial_edge = partial(edge_function,G,M,Forest,unmarked_edges,tree_to_root,tree_num_of_v,root_of_v,v,Blossom_stack)
        #PARALLEL LOOP!
        temp = pool.map(partial_edge, edge_data)
        pool.terminate()

        for i in xrange(len(temp)): ######## could be parallelized
            if temp[i] != None and (temp[i][0] == 2 or temp[i][0] == 3):
                return temp[i][1]
        # Not CASE 2 or 3
        ## check for blossoms of 3-length
        for i in xrange(len(temp)): ######## could be parallelized
            if temp[i] != None and (temp[i][0] == 1 and G.has_edge(v,temp[i][1][1])):
                #contract len 3 blossom
                w = temp[i][1][0]                
                blossom = [v,w,temp[i][1][1],v]
                contracted_G = copy.deepcopy(G)
                contracted_M = copy.deepcopy(M)
                for node in blossom[0:len(blossom)-1]:
                    if node != w:
                        contracted_G = nx.contracted_nodes(contracted_G, w, node, self_loops=False)
                        if node in contracted_M.nodes(): 
                           edge_rm = list(M.edges(node))[0] #this will be exactly one edge
                           contracted_M.remove_node(node)
                           contracted_M.remove_node(edge_rm[1])
                           # assert(len(list(contracted_M.nodes()))%2 == 0)

                # add blossom to our stack
                Blossom_stack.append(w)

                # recurse
                aug_path = finding_aug_path(contracted_G, contracted_M, Blossom_stack)

                # check if blossom exists in aug_path 
                v_B = Blossom_stack.pop()
                if (v_B in aug_path):
                    ##Define the L_stem and R_stem
                    L_stem = aug_path[0:aug_path.index(v_B)]
                    R_stem = aug_path[aug_path.index(v_B)+1:]
                    lifted_blossom = [] #stores the path within the blossom to take

                    # Find base of blossom
                    i = 0
                    base = None
                    base_idx = -1
                    blossom_ext = blossom + [blossom[1]] 
                    while base == None and i < len(blossom) - 1:
                        if not(M.has_edge(blossom[i],blossom[i+1])):
                            if not(M.has_edge(blossom[i+1],blossom_ext[i+2])): 
                                base = blossom[i+1]
                                base_idx = i+1
                            else:
                                i += 2
                        else:
                            i += 1
                    # if needed, create list of blossom nodes starting at base
                    if blossom[0] != base:
                        based_blossom = []
                        base_idx = blossom.index(base)
                        for i in xrange(base_idx,len(blossom)-1):
                            based_blossom.append(blossom[i])
                        for i in xrange(0,base_idx):
                            based_blossom.append(blossom[i])
                        based_blossom.append(base)
                    else:
                        based_blossom = blossom

                    # CHECK IF BLOSSOM IS ENDPT
                    if L_stem == [] or R_stem == []:
                        if L_stem != []:
                            if G.has_edge(base, L_stem[-1]):
                                # CASE 1:
                                # Chuck the blossom
                                return L_stem + [base]
                            else:
                                # CASE 2:
                                # find where Lstem is connected
                                i = 1
                                while (lifted_blossom == []):
                                    # assert(i < len(based_blossom)-1)
                                    if G.has_edge(based_blossom[i],L_stem[-1]):
                                        # make sure we're adding the even part to lifted path
                                        if i%2 == 0: # same dir path
                                            lifted_blossom = list(reversed(based_blossom))[-i-1:] 
                                        else: # opposite dir path
                                            lifted_blossom = based_blossom[i:]
                                    i += 1
                                return L_stem + lifted_blossom

                        else:
                            # R is not empty, L is empty
                            if G.has_edge(base, R_stem[0]):
                                # CASE 1:
                                # Chuck the blossom. 
                                return [base] + R_stem
                            else:
                                # CASE 2:
                                # find where R_stem is connected
                                i = 1
                                while (lifted_blossom == []):
                                    # assert(i < len(based_blossom)-1)
                                    if G.has_edge(based_blossom[i],R_stem[0]):
                                        # make sure we're adding the even part to lifted path
                                        if i%2 == 0: # same dir path
                                            lifted_blossom = based_blossom[:i+1]
                                            # print lifted_blossom
                                        else: # opposite dir path
                                            lifted_blossom = list(reversed(based_blossom))[:-i]
                                    i += 1
                                return lifted_blossom + R_stem

                    else: # blossom is in the middle
                        # LIFT the blossom
                        # check if L_stem attaches to base
                        if M.has_edge(base, L_stem[-1]):
                            # find where right stem attaches
                            if G.has_edge(base, R_stem[0]):
                                # blossom is useless
                                return L_stem + [base] + R_stem
                            else:
                                # blossom needs to be lifted
                                i = 1
                                while (lifted_blossom == []):
                                    # assert(i < len(based_blossom)-1)
                                    if G.has_edge(based_blossom[i],R_stem[0]):
                                        # make sure we're adding the even part to lifted path
                                        if i%2 == 0: # same dir path
                                            lifted_blossom = based_blossom[:i+1] 
                                            print lifted_blossom
                                        else: # opposite dir path
                                            lifted_blossom = list(reversed(based_blossom))[:-i]
                                            print lifted_blossom

                                    i += 1
                                return L_stem + lifted_blossom + R_stem
                        else: 
                            # R stem to base is in matching
                            assert(M.has_edge(base, R_stem[0]))
                            # check where left stem attaches
                            if G.has_edge(base, L_stem[-1]):
                                # blossom is useless
                                return L_stem + [base] + R_stem
                            else:
                                # blossom needs to be lifted
                                i = 1
                                while (lifted_blossom == []):
                                    # assert(i < len(based_blossom)-1)
                                    if G.has_edge(based_blossom[i],L_stem[-1]):
                                        # make sure we're adding the even part to lifted path
                                        if i%2 == 0: # same dir path
                                            lifted_blossom = list(reversed(based_blossom))[-i-1:] 
                                        else: # opposite dir path
                                            lifted_blossom = based_blossom[i:] 
                                    i += 1
                                return L_stem + list((lifted_blossom)) + R_stem

                else: # blossom is not in aug_path
                    return aug_path

        for i in xrange(len(temp)):
            if temp[i] != None and temp[i][0] ==1:
                Forest[tree_num_of_v].add_edge(v,temp[i][1][0])
                Forest[tree_num_of_v].add_edge(temp[i][1][0],temp[i][1][1])
                Forest_nodes.append(temp[i][1][1])

    return [] #Empty Path