%PDF- %PDF-
| Direktori : /lib/python3/dist-packages/pythran/ |
| Current File : //lib/python3/dist-packages/pythran/graph.py |
'''
Minimal directed graph replacement for networkx.DiGraph
This has the sole advantage of being a standalone file that doesn't bring any
dependency with it.
'''
class DiGraph(object):
def __init__(self):
# adjacency[i][j] = True means j is a successor of i
self._adjacency = {}
self._edges = {}
def successors(self, node):
return (n for n in self._adjacency[node])
def predecessors(self, node):
return (k for k, v in self._adjacency.items() if node in v)
def add_node(self, node):
self._adjacency.setdefault(node, set())
def add_edge(self, src, dest, **props):
self.add_node(dest)
self._adjacency.setdefault(src, set()).add(dest)
self._edges[(src, dest)] = props
@property
def edges(self):
return self._edges
def remove_edge(self, src, dest):
self._adjacency[src].remove(dest)
del self._edges[(src, dest)]
def __len__(self):
return len(self._adjacency)
def __iter__(self):
return iter(self._adjacency.keys())
def __contains__(self, value):
return value in self._adjacency
def __getitem__(self, node):
return self._adjacency[node]
class Unfeasible(RuntimeError):
pass
def has_path(graph, src, dest):
visited = set()
worklist = [src]
while worklist:
current = worklist.pop()
if current in visited:
continue
visited.add(current)
if dest in graph.successors(current):
return True
worklist.extend(graph.successors(current))
return False
# Copied verbatim from NetworkX 2.6.1
#
# NetworkX is distributed with the 3-clause BSD license.
#
# ::
#
# Copyright (C) 2004-2021, NetworkX Developers
# Aric Hagberg <hagberg@lanl.gov>
# Dan Schult <dschult@colgate.edu>
# Pieter Swart <swart@lanl.gov>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# * Neither the name of the NetworkX Developers nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
def _all_simple_paths_graph(G, source, targets, cutoff):
visited = dict.fromkeys([source])
stack = [iter(G[source])]
while stack:
children = stack[-1]
child = next(children, None)
if child is None:
stack.pop()
visited.popitem()
elif len(visited) < cutoff:
if child in visited:
continue
if child in targets:
yield list(visited) + [child]
visited[child] = None
if targets - set(visited.keys()): # expand stack until find all targets
stack.append(iter(G[child]))
else:
visited.popitem() # maybe other ways to child
else: # len(visited) == cutoff:
for target in (targets & (set(children) | {child})) - set(visited.keys()):
yield list(visited) + [target]
stack.pop()
visited.popitem()
def all_simple_paths(graph, src, target):
return _all_simple_paths_graph(graph, src, {target}, len(graph) - 1)