Example #1
0
    def subnet_tree(self, subnets=None):
        """Get a hierarchy tree of non-trivial subnets

        In this tree root is the current Pnet itself
        And one subnet is the child of another if child subnet is fully contained in parent subnet


        Tree has an additional labels on nodes and egdes

        For nodes, label 'inner' contains tuple with keys of edges from starting node of the subnet,
        that are a part of this subnet
        (some start node's outgoing edges may be not a part of the subnet)

        For edges, label 'keys' contains tuple with keys of edges from start of the parent subnet,
        that lead to the start node of child subnet
        (or childs' 'inner' label, if child and parent start from the same node)

        Parameters
        ----------
        subnets : container of (int,int), optional
            list or other container with all non-trivial subnets of current Pnet
            if not given, it will be calculated automatically

        Returns
        -------
        tree : networkx.DiGraph
            Subnet hierarchy tree with additional labels

        See Also
        --------
        subnets, envelope_subnet
        """
        subnets = subnets if subnets is not None else self.subnets()

        tree = nx.DiGraph()

        for subnet in subnets:
            subnet_start, subnet_end = subnet
            envelope_subnet = self.envelope_subnet(subnet, subnets=subnets)

            inner_paths = nx.all_simple_edge_paths(self, subnet_start,
                                                   subnet_end)
            inner_keys = tuple(set(k for (_, _, k), *_ in inner_paths))

            if envelope_subnet is None:
                tree.add_node(subnet, inner=inner_keys)
            else:
                envelop_start = envelope_subnet[0]

                if subnet_start == envelop_start:
                    paths = nx.all_simple_edge_paths(self, envelop_start,
                                                     subnet_end)
                else:
                    paths = nx.all_simple_edge_paths(self, envelop_start,
                                                     subnet_start)
                keys = tuple(set(k for (_, _, k), *_ in paths))
                tree.add_node(subnet, inner=inner_keys)
                tree.add_edge(envelope_subnet, subnet, keys=keys)

        return tree
Example #2
0
def test_all_simple_edge_paths_cutoff():
    G = nx.complete_graph(4)
    paths = nx.all_simple_edge_paths(G, 0, 1, cutoff=1)
    assert {tuple(p) for p in paths} == {((0, 1), )}
    paths = nx.all_simple_edge_paths(G, 0, 1, cutoff=2)
    assert {tuple(p)
            for p in paths} == {((0, 1), ), ((0, 2), (2, 1)), ((0, 3), (3, 1))}
Example #3
0
def test_all_simple_edge_paths_on_non_trivial_graph():
    """ you may need to draw this graph to make sure it is reasonable """
    G = nx.path_graph(5, create_using=nx.DiGraph())
    G.add_edges_from([(0, 5), (1, 5), (1, 3), (5, 4), (4, 2), (4, 3)])
    paths = nx.all_simple_edge_paths(G, 1, [2, 3])
    assert {tuple(p)
            for p in paths} == {
                ((1, 2), ),
                ((1, 3), (3, 4), (4, 2)),
                ((1, 5), (5, 4), (4, 2)),
                ((1, 3), ),
                ((1, 2), (2, 3)),
                ((1, 5), (5, 4), (4, 3)),
                ((1, 5), (5, 4), (4, 2), (2, 3)),
            }
    paths = nx.all_simple_edge_paths(G, 1, [2, 3], cutoff=3)
    assert {tuple(p)
            for p in paths} == {
                ((1, 2), ),
                ((1, 3), (3, 4), (4, 2)),
                ((1, 5), (5, 4), (4, 2)),
                ((1, 3), ),
                ((1, 2), (2, 3)),
                ((1, 5), (5, 4), (4, 3)),
            }
    paths = nx.all_simple_edge_paths(G, 1, [2, 3], cutoff=2)
    assert {tuple(p)
            for p in paths} == {((1, 2), ), ((1, 3), ), ((1, 2), (2, 3))}
Example #4
0
 def all_routes():
     for start, end in itertools.combinations(G.nodes(), 2):
         for path in nx.all_simple_edge_paths(G, start, end):
             if len(path) == len(G.nodes()) - 1:
                 yield path
         for path in nx.all_simple_edge_paths(G, end, start):
             if len(path) == len(G.nodes()) - 1:
                 yield path
Example #5
0
def test_all_simple_edge_paths_multigraph():
    G = nx.MultiGraph([(1, 2), (1, 2)])
    paths = nx.all_simple_edge_paths(G, 1, 1)
    assert list(paths) == []
    nx.add_path(G, [3, 1, 10, 2])
    paths = list(nx.all_simple_edge_paths(G, 1, 2))
    assert len(paths) == 3
    assert {tuple(p) for p in paths} == {
        ((1, 2, 0),), ((1, 2, 1),), ((1, 10, 0), (10, 2, 0))
        }
Example #6
0
def test_all_simple_edge_paths_with_two_targets_emits_two_paths():
    G = nx.path_graph(4)
    G.add_edge(2, 4)
    paths = nx.all_simple_edge_paths(G, 0, [3, 4])
    assert {tuple(p) for p in paths} == {
        ((0, 1), (1, 2), (2, 3)), ((0, 1), (1, 2), (2, 4))
        }
Example #7
0
    def sents(self, start=None, end=None, maxlen=None):
        """Generate sentences from paths between start and end nodes

        Parameters
        ----------
        start : int, default self.start
            node to start sentence from
        end : int, default self.end
            node where the sentence ends
        maxlen : int, default None
            maximum length (in the number of keys) of sentences to return,
            unlimited if equals to None

        Yields
        -------
        sent: list of str
            sentence as list of edges labels/keys

        See Also
        --------
        add_sents
        """
        start = start if start is not None else self.start
        end = end if end is not None else self.end

        paths = nx.all_simple_edge_paths(self, start, end, cutoff=maxlen)

        for path in paths:
            sent = []
            for _, _, word in path:
                sent += word
            yield sent
Example #8
0
 def length(self, start=None, end=None):
     start = start if start is not None else self.start
     end = end if end is not None else self.end
     return len(
         max(list(nx.all_simple_edge_paths(self, start, end)),
             key=len,
             default=[]))
Example #9
0
def test_series_diagram_construction():
    head_block = DirectFormI.from_model(
        signal.dlti(1, [1, 1, 0.5]))
    tail_block = DirectFormI.from_model(
        signal.dlti(2, [1, -0.5]))
    x, y = sympy.symbols('x y')

    diagram = series_diagram([
        head_block, tail_block
    ], input_=x, output=y)

    paths = list(nx.all_simple_edge_paths(
        diagram, source=x, target=y))
    assert len(paths) == 1
    path = paths[0]
    assert len(path) == 2
    u, v, i = path[0]
    assert u is x
    assert i == 0
    assert diagram[u][v][i]['block'] is head_block

    w, z, i = path[1]
    assert v is w
    assert z is y
    assert i == 0
    assert diagram[w][z][i]['block'] is tail_block
Example #10
0
def test_digraph_all_simple_edge_paths_with_two_targets_cutoff():
    G = nx.path_graph(4, create_using=nx.DiGraph())
    G.add_edge(2, 4)
    paths = nx.all_simple_edge_paths(G, 0, [3, 4], cutoff=3)
    assert {tuple(p) for p in paths} == {
        ((0, 1), (1, 2), (2, 3)), ((0, 1), (1, 2), (2, 4))
        }
Example #11
0
def hamiltonian_edge_path(G, source):
    source = arbitrary_element(G)
    neighbors = set(G[source]) - {source}
    n = len(G)
    for target in neighbors:
        for path in nx.all_simple_edge_paths(G, source, target):
            if len(path) == n - 1:
                yield path
def check_explicit_flow(rda_graph, source, target):
    paths = nx.all_simple_edge_paths(rda_graph, source=source, target=target)
    for path in paths:
        valid = True
        for edge in path:
            if rda_graph.get_edge_data(edge[0],edge[1])['type'] == 1:
                valid = False
                break
        if valid:
            return path
    return None
Example #13
0
    def get_causal_paths(self,
                         as_edge_list: bool = False) -> List[List[Tuple]]:
        if self.treatment is None or self.outcome is None:
            return []

        if as_edge_list:
            paths = nx.all_simple_edge_paths(self._graph, self.treatment,
                                             self.outcome)
        else:
            paths = nx.all_simple_paths(self._graph, self.treatment,
                                        self.outcome)
        return list(paths)
Example #14
0
    def getAllPaths(self, terminalNodes):

        paths = []

        for t in terminalNodes:
            for p in nx.all_simple_edge_paths(
                    self.dot, source=self.root,
                    target=t):  #get all paths to that termIndice
                newPath = []
                for edge in range(len(p)):  #iterate through edges
                    node0 = p[edge][0]
                    node1 = p[edge][1]

                    if edge + 1 == len(p):  #last edge pair

                        lbl = self.dot.nodes[node0]['label'].split('\\n')
                        var0 = lbl[0]

                        lbl2 = self.dot.nodes[node1]['label'].split('\\n')
                        cls = lbl2[-1].replace("class = ", "")
                        cls = cls.replace("\"", "")
                        relop, param = self.dot.get_edge_data(
                            node0, node1)['label'].split(" ")
                        op = '==>'

                        newPath.append(var0)
                        newPath.append(relop)
                        newPath.append(param)
                        newPath.append(op)
                        newPath.append(cls)

                    else:
                        lbl = self.dot.nodes[node0]['label'].split('\\n')
                        var0 = lbl[0]
                        relop, param = self.dot.get_edge_data(
                            node0, node1)['label'].split(" ")

                        if self.dot.get_edge_data(node0,
                                                  node1)['style'] == 'solid':
                            op = 'AND'
                        else:
                            op = 'OR'

                        newPath.append(var0)
                        newPath.append(relop)
                        newPath.append(param)
                        newPath.append(op)

                paths.append(newPath)

        return paths
Example #15
0
    def get_row_indices(self, table: LinkedTable, source_node: Union[int, str],
                        target_node: Union[int, str], links: Tuple[str, str]):
        assert isinstance(source_node, int) or isinstance(
            target_node, int), "Can only get row index for at least one column"
        if isinstance(source_node, str):
            if table.context.page_qnode == source_node:
                # TODO: get context node id, is there any better way to do it?
                source_id = f"ent:{source_node}"
            else:
                source_id = f"ent:{source_node}"
        else:
            source_id = f"column-{source_node}"

        if isinstance(target_node, str):
            # TODO: fix me after we fix the data graph
            if table.context.page_qnode == target_node:
                # TODO: get context node id, is there any better way to do it?
                target_id = f"ent:{target_node}"
            else:
                target_id = f"ent:{target_node}"
        else:
            target_id = f"column-{target_node}"

        dg, sg = self.table2g[table.id]
        rows = set()
        for paths in nx.all_simple_edge_paths(sg,
                                              source_id,
                                              target_id,
                                              cutoff=2):
            assert len(paths) == 2
            uid, sid, eid = paths[0]
            _, vid, peid = paths[1]

            if not (eid == links[0] and peid == links[1]):
                continue

            stmt: SGStatementNode = sg.nodes[sid]['data']
            for (source_flow, target_flow), stmt2prov in stmt.flow.items():
                if target_flow.sg_target_id == vid and target_flow.edge_id == peid:
                    dv = dg.nodes[target_flow.dg_target_id]['data']
                    if dv.is_cell:
                        rows.add(dv.row)
                    else:
                        du = dg.nodes[source_flow.dg_source_id]['data']
                        assert du.is_cell
                        rows.add(du.row)
        return rows
Example #16
0
 def compounds(self) -> List[str]:
     """
     For this example, we define compounds as linear sub-graphs (paths) of any length.
     """
     if hasattr(self, "_compounds"):
         return self._compounds
     else:
         self._compounds = []
         for a1, a2 in product(self.atoms, self.atoms):
             new_compounds = [SETCompound(self.G.edge_subgraph(p), self.G, self.id) 
                              for p in list(nx.all_simple_edge_paths(
                                      self.G, source=a1, target=a2)) if p]
             self._compounds += new_compounds
         
         # otherwise we will double count subgraphs
         self._compounds = set(self._compounds)
         for c in self._compounds:
             self.compounds_by_type[str(c)].append(c)
         return self._compounds
Example #17
0
def _getShortestPathInMultigraph(G, Source, Target):
    edges = []
    if not (G.has_node(Source) and G.has_node(Target)):
        return edges

    try:
        # pathLength = nx.shortest_path_length(G, Source, Target)
        Node_path = nx.shortest_path(G, Source, Target)
        if len(Node_path) == 0:
            return edges
        for index in range(len(Node_path) - 1):
            edge_path = nx.all_simple_edge_paths(G, Node_path[index],
                                                 Node_path[index + 1], 1)
            edges.append(next(edge_path)[0])

        # all_edge_paths = nx.all_simple_edge_paths(G, Source, Target, pathLength)
        # edges = next(all_edge_paths)

    except:
        edges = []
    return edges
def tree_to_leaf_row_values(
        tree: nx.DiGraph, row_value_fn: Callable,
        default_row_values: Dict[str, Number]) -> Dict[str, Dict[str, Number]]:
    """
    Return, for list of leaf nodes, a dictionary mapping column name to value to generate. Note: not implemented for
    recurring instances of the same feature along a single path to a leaf.
    """
    leaf_row_values = {}
    # Get root name
    root_name = [n for (n, d) in tree.in_degree() if d == 0][0]
    # Get criteria for each leaf
    for node in tree:
        if tree.out_degree(node) == 0:  # leaf node
            criteria = {}
            for path in next(
                    nx.all_simple_edge_paths(tree, root_name, node)
            ):  # only one path, so calling next() once gets it (math.stackexchange.com/a/1523566/440173)
                criteria[path[0]] = tree.edges[path]["criterion"]

            # Translate criteria to row value dict
            leaf_row_values[node] = row_value_fn(criteria, default_row_values)

    return leaf_row_values
Example #19
0
def _subnet_to_rule(net, subnet, subnet_tree, non_terms):
    sub_children = list(subnet_tree.successors(subnet))

    s_to_e = {}
    for s, e in sub_children:
        if s not in s_to_e:
            s_to_e[s] = [e]
        else:
            s_to_e[s].append(e)

    paths = nx.all_simple_edge_paths(net, subnet[0], subnet[1])
    res = set()

    for path in paths:
        subnet_s = None
        variant = ''
        for s, e, k in path:
            if subnet_s is not None and s in s_to_e[subnet_s]:
                variant += ' ' + non_terms[(subnet_s, s)]
                subnet_s = None

            if s in s_to_e:
                subnet_s = s

            if subnet_s is not None:
                continue

            variant += ' ' + f"'{k}'"

        # if child subnet ends on the same node as parent
        if subnet_s is not None:
            variant += ' ' + non_terms[(subnet_s, subnet[1])]

        res.add(variant)

    rule = non_terms[subnet] + ' ->' + ' |'.join(res)
    return rule
Example #20
0
def _schema_fields_from_dag(
    graph: nx.DiGraph, is_key_schema: bool
) -> List[SchemaField]:
    generations: List = list(nx.algorithms.dag.topological_generations(graph))
    fields: Dict = {}

    if generations and generations[0]:
        roots = generations[0]
        leafs: List = []
        for node in graph:
            if graph.out_degree(node) == 0:
                leafs.append(node)

        type_of_nodes: Dict = nx.get_node_attributes(graph, "node_type")

        for root in roots:
            root_type = type_of_nodes[root]
            for leaf in leafs:
                paths = list(nx.all_simple_edge_paths(graph, root, leaf))
                if paths:
                    for path in paths:
                        stack: List[str] = ["[version=2.0]"]
                        if is_key_schema:
                            stack.append("[key=True]")
                        stack.append(root_type)
                        if len(roots) > 1:
                            stack.append(re.sub(r"^.*\.", "", root))
                            root_path = ".".join(stack)
                            fields[root_path] = SchemaField(
                                fieldPath=root_path,
                                nativeDataType="message",
                                type=SchemaFieldDataType(type=RecordTypeClass()),
                            )
                        for field in _traverse_path(graph, path, stack):
                            fields[field.path] = field.field

    return sorted(fields.values(), key=lambda sf: sf.fieldPath)
Example #21
0
def test_all_simple_edge_paths():
    G = nx.path_graph(4)
    paths = nx.all_simple_edge_paths(G, 0, 3)
    assert {tuple(p) for p in paths} == {((0, 1), (1, 2), (2, 3))}
Example #22
0
def test_edge_target_missing():
    with pytest.raises(nx.NodeNotFound):
        G = nx.Graph()
        nx.add_path(G, [1, 2, 3])
        list(nx.all_simple_edge_paths(nx.MultiGraph(G), 1, 4))
Example #23
0
def test_all_simple_edge_paths_ignores_cycle():
    G = nx.cycle_graph(3, create_using=nx.DiGraph())
    G.add_edge(1, 3)
    paths = nx.all_simple_edge_paths(G, 0, 3)
    assert {tuple(p) for p in paths} == {((0, 1), (1, 3))}
Example #24
0
def test_all_simple_edge_paths_with_two_targets_inside_cycle_emits_two_paths():
    G = nx.cycle_graph(3, create_using=nx.DiGraph())
    G.add_edge(1, 3)
    paths = nx.all_simple_edge_paths(G, 0, [2, 3])
    assert {tuple(p) for p in paths} == {((0, 1), (1, 2)), ((0, 1), (1, 3))}
Example #25
0
def test_edge_cutoff_zero():
    G = nx.complete_graph(4)
    paths = nx.all_simple_edge_paths(G, 0, 3, cutoff=0)
    assert list(list(p) for p in paths) == []
    paths = nx.all_simple_edge_paths(nx.MultiGraph(G), 0, 3, cutoff=0)
    assert list(list(p) for p in paths) == []
Example #26
0
def test_all_simple_edge_paths_corner_cases():
    assert list(nx.all_simple_edge_paths(nx.empty_graph(2), 0, 0)) == []
    assert list(nx.all_simple_edge_paths(nx.empty_graph(2), 0, 1)) == []
    assert list(nx.all_simple_edge_paths(nx.path_graph(9), 0, 8, 0)) == []
Example #27
0
def test_all_simple_edge_paths_empty():
    G = nx.path_graph(4)
    paths = nx.all_simple_edge_paths(G, 0, 3, cutoff=2)
    assert list(paths) == []
Example #28
0
def test_all_simple_edge_paths_directed():
    G = nx.DiGraph()
    nx.add_path(G, [1, 2, 3])
    nx.add_path(G, [3, 2, 1])
    paths = nx.all_simple_edge_paths(G, 1, 3)
    assert {tuple(p) for p in paths} == {((1, 2), (2, 3))}
Example #29
0
def test_all_simple_edge_paths_multigraph_with_cutoff():
    G = nx.MultiGraph([(1, 2), (1, 2), (1, 10), (10, 2)])
    paths = list(nx.all_simple_edge_paths(G, 1, 2, cutoff=1))
    assert len(paths) == 2
    assert {tuple(p) for p in paths} == {((1, 2, 0), ), ((1, 2, 1), )}
Example #30
0
def test_all_simple_edge_paths_source_target():
    G = nx.path_graph(4)
    paths = nx.all_simple_edge_paths(G, 1, 1)
    assert list(paths) == []