Example #1
0
def get_all_zero_edges(G, s, t, topological_dict):
    """
    Get all "zero-edges" from a graph: all the edges that if we remove them,
    the graph won't be connected anymore.
    """
    if nx.min_cut(G, s, t) != 1:
        return []
    auxiliary = nx.copy.deepcopy(G)
    zero_edges = nx.bidirectional_shortest_path(auxiliary, s, t)
    zero_edges = list(zip(zero_edges[:-1], zero_edges[1:]))

    kill_list = []
    for edge in zero_edges:

        auxiliary.remove_edge(edge[0], edge[1])

        try:
            nx.bidirectional_shortest_path(auxiliary, s, t)
            print edge
            kill_list.append(edge)
        except nx.NetworkXNoPath:
            pass
        auxiliary.add_edge(edge[0], edge[1])

    for edge in kill_list:
        zero_edges.remove(edge)
    zero_edges.sort(lambda x, y: cmp(topological_dict[x[0]], topological_dict[y[0]]))
    return zero_edges
Example #2
0
 def test_bidirectional_shortest_path(self):
     assert_equal(nx.bidirectional_shortest_path(self.cycle,0,3),
                  [0, 1, 2, 3])
     assert_equal(nx.bidirectional_shortest_path(self.cycle,0,4),
                  [0, 6, 5, 4])
     validate_grid_path(4, 4, 1, 12, nx.bidirectional_shortest_path(self.grid,1,12))
     assert_equal(nx.bidirectional_shortest_path(self.directed_cycle,0,3),
                  [0, 1, 2, 3])
Example #3
0
 def test_bidirectional_shortest_path(self):
     assert_equal(nx.bidirectional_shortest_path(self.cycle,0,3),
                  [0, 1, 2, 3])
     assert_equal(nx.bidirectional_shortest_path(self.cycle,0,4),
                  [0, 6, 5, 4])
     assert_equal(nx.bidirectional_shortest_path(self.grid,1,12),
                  [1, 2, 3, 4, 8, 12])
     assert_equal(nx.bidirectional_shortest_path(self.directed_cycle,0,3),
                  [0, 1, 2, 3])
Example #4
0
def ford_fulkerson_impl(G, s, t, capacity):
    """Legacy implementation of the Edmonds-Karp algorithm"""
    if G.is_multigraph():
        raise nx.NetworkXError(
                'MultiGraph and MultiDiGraph not supported (yet).')

    if s not in G:
        raise nx.NetworkXError('node %s not in graph' % str(s))
    if t not in G:
        raise nx.NetworkXError('node %s not in graph' % str(t))
    if s == t:
        raise nx.NetworkXError('source and sink are the same node')

    auxiliary = _create_auxiliary_digraph(G, capacity=capacity)
    inf_capacity_flows = auxiliary.graph['inf_capacity_flows']

    flow_value = 0   # Initial feasible flow.

    # As long as there is an (s, t)-path in the auxiliary digraph, find
    # the shortest (with respect to the number of arcs) such path and
    # augment the flow on this path.
    while True:
        try:
            path_nodes = nx.bidirectional_shortest_path(auxiliary, s, t)
        except nx.NetworkXNoPath:
            break

        # Get the list of edges in the shortest path.
        path_edges = list(zip(path_nodes[:-1], path_nodes[1:]))

        # Find the minimum capacity of an edge in the path.
        try:
            path_capacity = min([auxiliary[u][v][capacity]
                                for u, v in path_edges
                                if capacity in auxiliary[u][v]])
        except ValueError:
            # path of infinite capacity implies no max flow
            raise nx.NetworkXUnbounded(
                    "Infinite capacity path, flow unbounded above.")

        flow_value += path_capacity

        # Augment the flow along the path.
        for u, v in path_edges:
            edge_attr = auxiliary[u][v]
            if capacity in edge_attr:
                edge_attr[capacity] -= path_capacity
                if edge_attr[capacity] == 0:
                    auxiliary.remove_edge(u, v)
            else:
                inf_capacity_flows[(u, v)] += path_capacity

            if auxiliary.has_edge(v, u):
                if capacity in auxiliary[v][u]:
                    auxiliary[v][u][capacity] += path_capacity
            else:
                auxiliary.add_edge(v, u, {capacity: path_capacity})

    auxiliary.graph['inf_capacity_flows'] = inf_capacity_flows
    return flow_value, auxiliary
Example #5
0
File: geo.py Project: dpinney/omf
def shortestPathOmd(pathToOmdFile, sourceObjectName, targetObjectName):
	'''Get the shortest path between two points on a feeder'''
	with open(pathToOmdFile) as inFile:
		tree = json.load(inFile)['tree']
	nxG = omf.feeder.treeToNxGraph(tree)
	nxG = graphValidator(pathToOmdFile, nxG)
	tracePath = nx.bidirectional_shortest_path(nxG, sourceObjectName, targetObjectName)
	return tracePath
def output_go_terms_and_levels(go_terms, go, output_file, root_id="GO:0008150"):
    """
	root_id = "GO:0008150" # BP
    """
    from networkx import bidirectional_shortest_path
    f_out = open(output_file, 'w')
    f_out.write("go level\n")
    for go_id in go_terms:
	level = len(bidirectional_shortest_path(go, go_id, root_id))
	f_out.write("%s %d\n" % (go_id, level)) 
    f_out.close()
    return
Example #7
0
 def test_bidirectional_shortest_path_restricted(self):
     assert_equal(nx.bidirectional_shortest_path(self.cycle, 0, 3), [0, 1, 2, 3])
     assert_equal(nx.bidirectional_shortest_path(self.cycle, 0, 3, ignore_nodes=[1]), [0, 6, 5, 4, 3])
     assert_equal(nx.bidirectional_shortest_path(self.grid, 1, 12), [1, 2, 3, 4, 8, 12])
     assert_equal(nx.bidirectional_shortest_path(self.grid, 1, 12, ignore_nodes=[2]), [1, 5, 6, 10, 11, 12])
     assert_equal(nx.bidirectional_shortest_path(self.grid, 1, 12, ignore_nodes=[2, 6]), [1, 5, 9, 10, 11, 12])
     assert_equal(
         nx.bidirectional_shortest_path(self.grid, 1, 12, ignore_nodes=[2, 6], ignore_edges=[(10, 11)]),
         [1, 5, 9, 10, 14, 15, 16, 12],
     )
     assert_equal(nx.bidirectional_shortest_path(self.directed_cycle, 0, 3), [0, 1, 2, 3])
     assert_raises(nx.NetworkXNoPath, nx.bidirectional_shortest_path, self.directed_cycle, 0, 3, ignore_nodes=[1])
     assert_equal(nx.bidirectional_shortest_path(self.directed_cycle, 0, 3, ignore_edges=[(2, 1)]), [0, 1, 2, 3])
     assert_raises(
         nx.NetworkXNoPath, nx.bidirectional_shortest_path, self.directed_cycle, 0, 3, ignore_edges=[(1, 2)]
     )
Example #8
0
def shortest_path(source, target, transfer, lines, option="dijkstra"):
    """Find shortest path, using given lines"""
    reduced_lines = dict()
    reduced_subway = nx.Graph()
    for line in transfer:
        reduced_lines[line] = lines[line]

    for l in reduced_lines.values():
        for pair in pairwise(l.route):
            dist = np.linalg.norm([pair[0].xy, pair[1].xy])
            reduced_subway.add_edge(*pair, distance=dist)

    if option == "dijkstra":
        # least distance
        return nx.bidirectional_dijkstra(reduced_subway, source, target, weight="distance")
    else:
        # least stops
        return nx.bidirectional_shortest_path(reduced_subway, source, target)
Example #9
0
def shortest_path_length(G, source=None, target=None, weight=None):
    """Compute shortest path lengths in the graph.

    This function can compute the single source shortest path
    lengths by specifying only the source or all pairs shortest
    path lengths by specifying neither the source or target.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
       Starting node for path.
       If not specified compute shortest path lengths for all
       connected node pairs.

    target : node, optional
       Ending node for path.
       If not specified compute shortest path lengths for every
       node reachable from the source.

    weight : None or string, optional (default = None)
       If None, every edge has weight/distance/cost 1.
       If a string, use this edge attribute as the edge weight.
       Any edge attribute not present defaults to 1.

    Returns
    -------
    length : number, or container of numbers
        If the source and target are both specified return a
        single number for the shortest path.
        If only the source is specified return a dictionary keyed by
        targets with a the shortest path as keys.
        If neither the source or target is specified return a dictionary
        of dictionaries with length[source][target]=value.

    Raises
    ------
    NetworkXNoPath
        If no path exists between source and target.

    Examples
    --------
    >>> G=nx.path_graph(5)
    >>> print(nx.shortest_path_length(G,source=0,target=4))
    4
    >>> p=nx.shortest_path_length(G,source=0) # target not specified
    >>> p[4]
    4
    >>> p=nx.shortest_path_length(G) # source,target not specified
    >>> p[0][4]
    4

    Notes
    -----
    For digraphs this returns the shortest directed path.
    To find path lengths in the reverse direction use G.reverse(copy=False)
    first to flip the edge orientation.

    See Also
    --------
    all_pairs_shortest_path_length()
    all_pairs_dijkstra_path_length()
    single_source_shortest_path_length()
    single_source_dijkstra_path_length()

    """
    if source is None:
        if target is None:
            if weight is None:
                paths=nx.all_pairs_shortest_path_length(G)
            else:
                paths=nx.all_pairs_dijkstra_path_length(G, weight=weight)
        else:
            raise nx.NetworkXError("Target given but no source specified.")
    else: # source specified
        if target is None:
            if weight is None:
                paths=nx.single_source_shortest_path_length(G,source)
            else:
                paths=nx.single_source_dijkstra_path_length(G,source,weight=weight)
        else:
            # shortest source-target path
            if weight is None:
                p=nx.bidirectional_shortest_path(G,source,target)
                paths=len(p)-1
            else:
                paths=nx.dijkstra_path_length(G,source,target,weight)
    return paths
Example #10
0
def ford_fulkerson(G, s, t):
    """Find a maximum single-commodity flow using the Ford-Fulkerson
    algorithm.
    
    This algorithm uses Edmond-Karp-Dinitz path selection rule which
    guarantees a running time of O(|V||E|**2).

    Parameters
    ----------
    G : NetworkX graph
        Edges of the graph are expected to have an attribute called
        'capacity'. If this attribute is not present, the edge is
        considered to have infinite capacity.

    s : node
        Source node for the flow.

    t : node
        Sink node for the flow.

    Returns
    -------
    flowValue : integer, float
        Value of the maximum flow, i.e., net outflow from the source.

    flowGraph : NetworkX graph
        Graph with V(flowGraph) = V(G) and in which each edge has an
        attribute 'flow' which gives the flow on the edge.

    Raises
    ------
    NetworkXError
        If the graph has a path of infinite capacity, the value of a 
        feasible flow on the graph is unbounded above and the function
        raises a NetworkXError.

    Examples
    --------
    >>> import networkx as nx
    >>> G = nx.DiGraph()
    >>> G.add_edge('x','a', capacity = 3.0)
    >>> G.add_edge('x','b', capacity = 1.0)
    >>> G.add_edge('a','c', capacity = 3.0)
    >>> G.add_edge('b','c', capacity = 5.0)
    >>> G.add_edge('b','d', capacity = 4.0)
    >>> G.add_edge('d','e', capacity = 2.0)
    >>> G.add_edge('c','y', capacity = 2.0)
    >>> G.add_edge('e','y', capacity = 3.0)
    >>> flow,F=nx.ford_fulkerson(G, 'x', 'y')
    >>> flow
    3.0
    """
    
    auxiliary, infcapFlows = _create_auxiliary_digraph(G)
    flowValue = 0   # Initial feasible flow.

    # As long as there is an (s, t)-path in the auxiliary digraph, find
    # the shortest (with respect to the number of arcs) such path and
    # augment the flow on this path.
    while True:
        pathNodes = nx.bidirectional_shortest_path(auxiliary, s, t)
        if not pathNodes:
            break

        # Get the list of edges in the shortest path.
        pathEdges = []
        for i, u in enumerate(pathNodes[:-1]):
            v = pathNodes[i + 1]
            pathEdges.append((u, v, auxiliary[u][v]))

        # Find the minimum capacity of an edge in the path.
        try:
            pathCapacity = min([c['capacity']
                            for (u, v, c) in pathEdges
                            if c.has_key('capacity')])
        except ValueError: 
            # path of infinite capacity implies no max flow
            raise nx.NetworkXError(
                    "Infinite capacity path, flow unbounded above.")
        
        flowValue += pathCapacity

        # Augment the flow along the path.
        for (u, v, c) in pathEdges:
            auxEdgeAttr = auxiliary[u][v]
            if auxEdgeAttr.has_key('capacity'):
                auxEdgeAttr['capacity'] -= pathCapacity
                if auxEdgeAttr['capacity'] == 0:
                    auxiliary.remove_edge(u, v)
            else:
                infcapFlows[(u, v)] += pathCapacity

            if auxiliary.has_edge(v, u):
                if auxiliary[v][u].has_key('capacity'):
                    auxiliary[v][u]['capacity'] += pathCapacity
            else:
                auxiliary.add_edge(v, u, {'capacity': pathCapacity})
    
    flowGraph = _create_flow_graph(G, auxiliary, infcapFlows)
    return flowValue, flowGraph
Example #11
0
def shortest_path_length(G,source=None,target=None,weighted=False):
    """Compute shortest path lengths in the graph.
    
    This function can compute the single source shortest path
    lengths by specifying only the source or all pairs shortest
    path lengths by specifying neither the source or target.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
       Starting node for path.  
       If not specified compute shortest pats lenghts for all 
       connected node pairs.

    target : node, optional 
       Ending node for path.  
       If not specified compute shortest path lenghts for every 
       node reachable from the source.

    weighted : bool, optional
       If True consider weighted edges when finding shortest path length.

    Returns
    -------
    length : number, or container of numbers
        If the source and target are both specified return a
        single number for the shortest path.
        If only the source is specified return a dictionary keyed by
        targets with a the shortest path as keys.
        If neither the source or target is specified return a dictionary 
        of dictionaries with length[source][target]=value.

    Raises
    ------
    NetworkXNoPath
        If no path exists between source and target.

    Examples
    --------
    >>> G=nx.path_graph(5)
    >>> print(nx.shortest_path_length(G,source=0,target=4))
    4
    >>> p=nx.shortest_path_length(G,source=0) # target not specified
    >>> p[4]
    4
    >>> p=nx.shortest_path_length(G) # source,target not specified
    >>> p[0][4]
    4

    Notes
    -----
    If weighted=True and the graph has no 'weight' edge attribute
    the value 1 will be used.

    For digraphs this returns the shortest directed path.
    To find path lengths in the reverse direction use G.reverse(copy=False)
    first to flip the edge orientation.
    """
    if source is None:
        if target is None:
            if weighted:
                paths=nx.all_pairs_dijkstra_path_length(G)
            else:
                paths=nx.all_pairs_shortest_path_length(G)
        else:
            raise nx.NetworkXError(\
                "Target given but no source specified.")
    else: # source specified
        if target is None:
            if weighted:
                paths=nx.single_source_dijkstra_path_length(G,source)
            else:
                paths=nx.single_source_shortest_path_length(G,source)
        else:
            # shortest source-target path
            if weighted:
                paths=nx.dijkstra_path_length(G,source,target)
            else:
                p=nx.bidirectional_shortest_path(G,source,target)
                paths=len(p)-1
    return paths
Example #12
0
def shortest_path(G,source=None,target=None,weighted=False):
    """Compute shortest paths in the graph.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
       Starting node for path.  
       If not specified compute shortest paths for all connected node pairs.

    target : node, optional 
       Ending node for path.  
       If not specified compute shortest paths for every node reachable 
       from the source.

    weighted : bool, optional
       If True consider weighted edges when finding shortest path.

    Returns
    -------
    path: list or dictionary
        If the source and target are both specified return a single list
        of nodes in a shortest path.
        If only the source is specified return a dictionary keyed by
        targets with a list of nodes in a shortest path.
        If neither the source or target is specified return a dictionary 
        of dictionaries with path[source][target]=[list of nodes in path].

    Examples
    --------
    >>> G=nx.path_graph(5)
    >>> print(nx.shortest_path(G,source=0,target=4))
    [0, 1, 2, 3, 4]
    >>> p=nx.shortest_path(G,source=0) # target not specified
    >>> p[4]
    [0, 1, 2, 3, 4]
    >>> p=nx.shortest_path(G) # source,target not specified
    >>> p[0][4]
    [0, 1, 2, 3, 4]

    Notes
    -----
    There may be more than one shortest path between a source and target.
    This returns only one of them.

    If weighted=True and the graph has no 'weight' edge attribute
    the value 1 will be used.

    For digraphs this returns a shortest directed path.  
    To find paths in the reverse direction use G.reverse(copy=False)
    first to flip the edge orientation.
    """
    if source is None:
        if target is None:
            if weighted:
                paths=nx.all_pairs_dijkstra_path(G)
            else:
                paths=nx.all_pairs_shortest_path(G)
        else:
            raise nx.NetworkXError(\
                "Target given but no source specified.")
    else: # source specified
        if target is None:
            if weighted:
                paths=nx.single_source_dijkstra_path(G,source)
            else:
                paths=nx.single_source_shortest_path(G,source)
        else:
            # shortest source-target path
            if weighted:
                paths=nx.dijkstra_path(G,source,target)
            else:
                paths=nx.bidirectional_shortest_path(G,source,target)

    return paths
Example #13
0
def shortest_path_length(G, source=None, target=None, weight=None):
    """Compute shortest path lengths in the graph.
    
    This function can compute the single source shortest path
    lengths by specifying only the source or all pairs shortest
    path lengths by specifying neither the source or target.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
       Starting node for path.  
       If not specified compute shortest path lengths for all 
       connected node pairs.

    target : node, optional 
       Ending node for path.  
       If not specified compute shortest path lengths for every 
       node reachable from the source.

    weight : None, True or string, optional (default = None)
       If None, every edge has weight/distance/cost 1.
       If True, use the 'weight' edge attribute as the edge weight.
       If a string, use this edge attribute as the edge weight.
       Any edge attribute not present defaults to 1.

    Returns
    -------
    length : number, or container of numbers
        If the source and target are both specified return a
        single number for the shortest path.
        If only the source is specified return a dictionary keyed by
        targets with a the shortest path as keys.
        If neither the source or target is specified return a dictionary 
        of dictionaries with length[source][target]=value.

    Raises
    ------
    NetworkXNoPath
        If no path exists between source and target.

    Examples
    --------
    >>> G=nx.path_graph(5)
    >>> print(nx.shortest_path_length(G,source=0,target=4))
    4
    >>> p=nx.shortest_path_length(G,source=0) # target not specified
    >>> p[4]
    4
    >>> p=nx.shortest_path_length(G) # source,target not specified
    >>> p[0][4]
    4

    Notes
    -----
    For digraphs this returns the shortest directed path.
    To find path lengths in the reverse direction use G.reverse(copy=False)
    first to flip the edge orientation.

    See Also
    --------
    all_pairs_shortest_path_length()
    all_pairs_dijkstra_path_length()
    single_source_shortest_path_length()
    single_source_dijkstra_path_length()

    """
    if source is None:
        if target is None:
            if weight is None:
                paths = nx.all_pairs_shortest_path_length(G)
            else:
                if weight is True: weight = 'weight'
                paths = nx.all_pairs_dijkstra_path_length(G, weight=weight)
        else:
            raise nx.NetworkXError(\
                "Target given but no source specified.")
    else:  # source specified
        if target is None:
            if weight is None:
                paths = nx.single_source_shortest_path_length(G, source)
            else:
                if weight is True: weight = 'weight'
                paths = nx.single_source_dijkstra_path_length(G,
                                                              source,
                                                              weight=weight)
        else:
            # shortest source-target path
            if weight is None:
                p = nx.bidirectional_shortest_path(G, source, target)
                paths = len(p) - 1
            else:
                if weight is True: weight = 'weight'
                paths = nx.dijkstra_path_length(G, source, target, weight)
    return paths
Example #14
0
def ford_fulkerson(G, s, t, capacity='capacity'):
    """Find a maximum single-commodity flow using the Ford-Fulkerson
    algorithm.
    
    This algorithm uses Edmonds-Karp-Dinitz path selection rule which
    guarantees a running time of O(nm^2) for n nodes and m edges.


    Parameters
    ----------
    G : NetworkX graph
        Edges of the graph are expected to have an attribute called
        'capacity'. If this attribute is not present, the edge is
        considered to have infinite capacity.

    s : node
        Source node for the flow.

    t : node
        Sink node for the flow.

    capacity: string
        Edges of the graph G are expected to have an attribute capacity
        that indicates how much flow the edge can support. If this
        attribute is not present, the edge is considered to have
        infinite capacity. Default value: 'capacity'.

    Returns
    -------
    flow_value : integer, float
        Value of the maximum flow, i.e., net outflow from the source.

    flow_dict : dictionary
        Dictionary of dictionaries keyed by nodes such that
        flow_dict[u][v] is the flow edge (u, v).

    Raises
    ------
    NetworkXError
        The algorithm does not support MultiGraph and MultiDiGraph. If
        the input graph is an instance of one of these two classes, a
        NetworkXError is raised.

    NetworkXUnbounded
        If the graph has a path of infinite capacity, the value of a 
        feasible flow on the graph is unbounded above and the function
        raises a NetworkXUnbounded.

    Examples
    --------
    >>> import networkx as nx
    >>> G = nx.DiGraph()
    >>> G.add_edge('x','a', capacity=3.0)
    >>> G.add_edge('x','b', capacity=1.0)
    >>> G.add_edge('a','c', capacity=3.0)
    >>> G.add_edge('b','c', capacity=5.0)
    >>> G.add_edge('b','d', capacity=4.0)
    >>> G.add_edge('d','e', capacity=2.0)
    >>> G.add_edge('c','y', capacity=2.0)
    >>> G.add_edge('e','y', capacity=3.0)
    >>> flow, F = nx.ford_fulkerson(G, 'x', 'y')
    >>> flow
    3.0
    """
    if G.is_multigraph():
        raise nx.NetworkXError(
            'MultiGraph and MultiDiGraph not supported (yet).')

    if s not in G:
        raise nx.NetworkXError('node %s not in graph' % str(s))
    if t not in G:
        raise nx.NetworkXError('node %s not in graph' % str(t))

    auxiliary, inf_capacity_flows = _create_auxiliary_digraph(
        G, capacity=capacity)
    flow_value = 0  # Initial feasible flow.

    # As long as there is an (s, t)-path in the auxiliary digraph, find
    # the shortest (with respect to the number of arcs) such path and
    # augment the flow on this path.
    while True:
        try:
            path_nodes = nx.bidirectional_shortest_path(auxiliary, s, t)
        except nx.NetworkXNoPath:
            break

        # Get the list of edges in the shortest path.
        path_edges = list(zip(path_nodes[:-1], path_nodes[1:]))

        # Find the minimum capacity of an edge in the path.
        try:
            path_capacity = min([
                auxiliary[u][v][capacity] for u, v in path_edges
                if capacity in auxiliary[u][v]
            ])
        except ValueError:
            # path of infinite capacity implies no max flow
            raise nx.NetworkXUnbounded(
                "Infinite capacity path, flow unbounded above.")

        flow_value += path_capacity

        # Augment the flow along the path.
        for u, v in path_edges:
            edge_attr = auxiliary[u][v]
            if capacity in edge_attr:
                edge_attr[capacity] -= path_capacity
                if edge_attr[capacity] == 0:
                    auxiliary.remove_edge(u, v)
            else:
                inf_capacity_flows[(u, v)] += path_capacity

            if auxiliary.has_edge(v, u):
                if capacity in auxiliary[v][u]:
                    auxiliary[v][u][capacity] += path_capacity
            else:
                auxiliary.add_edge(v, u, {capacity: path_capacity})

    flow_dict = _create_flow_dict(G,
                                  auxiliary,
                                  inf_capacity_flows,
                                  capacity=capacity)
    return flow_value, flow_dict
Example #15
0
def main(s):
    maze = read_input(s)
    graph = nx.Graph()
    keys = {}
    doors = {}
    start = None
    for y in range(1, len(maze)-1):
        for x in range(1, len(maze[y])-1):
            symbol = maze[y][x]
            pos = (x, y)
            if symbol in string.ascii_uppercase:
                doors[pos] = symbol.lower()
            elif symbol in string.ascii_lowercase:
                keys[pos] = symbol
            elif symbol == "@":
                start = pos
                # keys[pos] = symbol
            if maze[y][x+1] != "#":
                graph.add_edge(pos, (x+1, y))
            if maze[y+1][x] != "#":
                graph.add_edge(pos, (x, y+1))
    for m in maze:
        print(m)

    least_steps = float('inf')
    step_cache = {}
    doors_cache = {}
    for ks in itertools.permutations(keys):
        picked_up_keys = []
        ks = list(ks)
        ks = [start] + ks
        path = []
        viable = True
        dks = set(doors.keys())
        for a, b in zip(ks[:], ks[1:]):
            if (a,b) in step_cache:
                steps = step_cache[(a,b)]
            else:
                steps = nx.bidirectional_shortest_path(graph, a, b)[1:]
                step_cache[(a,b)] = steps
            if (a,b) in doors_cache:
                doors_in_path = doors_cache[(a,b)]
            else:
                doors_in_path = dks.intersection(steps)
                doors_cache[(a,b)] = doors_in_path
            for d in doors_in_path:
                if doors[d] not in picked_up_keys:
                    viable = False
                    break
                else:
                    dks.remove(d)
            if not viable:
                break
            else:
                picked_up_keys.append(keys[b])
                path.extend(steps)
        if viable:
            if len(path) < least_steps:
                least_steps = len(path)
                print("poss", least_steps)

    return least_steps
Example #16
0
def shortest_path_length(G, source=None, target=None, weight=None):
    """Compute shortest path lengths in the graph.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
        Starting node for path.
        If not specified, compute shortest path lengths using all nodes as
        source nodes.

    target : node, optional
        Ending node for path.
        If not specified, compute shortest path lengths using all nodes as
        target nodes.

    weight : None or string, optional (default = None)
        If None, every edge has weight/distance/cost 1.
        If a string, use this edge attribute as the edge weight.
        Any edge attribute not present defaults to 1.

    Returns
    -------
    length: int or dictionary
        If the source and target are both specified, return the length of
        the shortest path from the source to the target.

        If only the source is specified, return a dictionary keyed by
        targets whose values are the lengths of the shortest path from the
        source to one of the targets.

        If only the target is specified, return a dictionary keyed by
        sources whose values are the lengths of the shortest path from one
        of the sources to the target.

        If neither the source nor target are specified return a dictionary
        of dictionaries with path[source][target]=L, where L is the length
        of the shortest path from source to target.

    Raises
    ------
    NetworkXNoPath
        If no path exists between source and target.

    Examples
    --------
    >>> G=nx.path_graph(5)
    >>> print(nx.shortest_path_length(G,source=0,target=4))
    4
    >>> p=nx.shortest_path_length(G,source=0) # target not specified
    >>> p[4]
    4
    >>> p=nx.shortest_path_length(G,target=4) # source not specified
    >>> p[0]
    4
    >>> p=nx.shortest_path_length(G) # source,target not specified
    >>> p[0][4]
    4

    Notes
    -----
    The length of the path is always 1 less than the number of nodes involved
    in the path since the length measures the number of edges followed.

    For digraphs this returns the shortest directed path length. To find path
    lengths in the reverse direction use G.reverse(copy=False) first to flip
    the edge orientation.

    See Also
    --------
    all_pairs_shortest_path_length()
    all_pairs_dijkstra_path_length()
    single_source_shortest_path_length()
    single_source_dijkstra_path_length()

    """
    if source is None:
        if target is None:
            ## Find paths between all pairs.
            if weight is None:
                paths=nx.all_pairs_shortest_path_length(G)
            else:
                paths=nx.all_pairs_dijkstra_path_length(G, weight=weight)
        else:
            ## Find paths from all nodes co-accessible to the target.
            directed = G.is_directed()
            if directed:
               G.reverse(copy=False)

            if weight is None:
                paths=nx.single_source_shortest_path_length(G,target)
            else:
                paths=nx.single_source_dijkstra_path_length(G,target,
                                                            weight=weight)

            if directed:
                G.reverse(copy=False)
    else:
        if target is None:
            ## Find paths to all nodes accessible from the source.
            if weight is None:
                paths=nx.single_source_shortest_path_length(G,source)
            else:
                paths=nx.single_source_dijkstra_path_length(G,source,weight=weight)
        else:
            ## Find shortest source-target path.
            if weight is None:
                p=nx.bidirectional_shortest_path(G,source,target)
                paths=len(p)-1
            else:
                paths=nx.dijkstra_path_length(G,source,target,weight)
    return paths
Example #17
0
def shortest_path(G,source=None,target=None,weighted=False):
    """Compute shortest paths in the graph.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
       Starting node for path.  
       If not specified compute shortest paths for all connected node pairs.

    target : node, optional 
       Ending node for path.  
       If not specified compute shortest paths for every node reachable 
       from the source.

    weighted : bool, optional
       If True consider weighted edges when finding shortest path.

    Returns
    -------
    path: list or dictionary
        If the source and target are both specified return a single list
        of nodes in a shortest path.
        If only the source is specified return a dictionary keyed by
        targets with a list of nodes in a shortest path.
        If neither the source or target is specified return a dictionary 
        of dictionaries with path[source][target]=[list of nodes in path].

    Examples
    --------
    >>> G=nx.path_graph(5)
    >>> print nx.shortest_path(G,source=0,target=4)
    [0, 1, 2, 3, 4]
    >>> p=nx.shortest_path(G,source=0) # target not specified
    >>> p[4]
    [0, 1, 2, 3, 4]
    >>> p=nx.shortest_path(G) # source,target not specified
    >>> p[0][4]
    [0, 1, 2, 3, 4]

    Notes
    -----
    There may be more than one shortest path between a source and target.
    This returns only one of them.

    If weighted=True and the graph has no 'weight' edge attribute
    the value 1 will be used.

    For digraphs this returns a shortest directed path.  
    To find paths in the reverse direction use G.reverse(copy=False)
    first to flip the edge orientation.
    """
    if source is None:
        if target is None:
            if weighted:
                paths=nx.all_pairs_dijkstra_path(G)
            else:
                paths=nx.all_pairs_shortest_path(G)
        else:
            raise nx.NetworkXError(\
                "Target given but no source specified.")
    else: # source specified
        if target is None:
            if weighted:
                paths=nx.single_source_dijkstra_path(G,source)
            else:
                paths=nx.single_source_shortest_path(G,source)
        else:
            # shortest source-target path
            if weighted:
                paths=nx.dijkstra_path(G,source,target)
            else:
                paths=nx.bidirectional_shortest_path(G,source,target)

    return paths
Example #18
0
def shortest_path(G, source=None, target=None, weight=None):
    """Compute shortest paths in the graph.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
        Starting node for path. If not specified, compute shortest
        paths for each possible starting node.

    target : node, optional
        Ending node for path. If not specified, compute shortest
        paths to all possible nodes.

    weight : None or string, optional (default = None)
        If None, every edge has weight/distance/cost 1.
        If a string, use this edge attribute as the edge weight.
        Any edge attribute not present defaults to 1.

    Returns
    -------
    path: list or dictionary
        All returned paths include both the source and target in the path.

        If the source and target are both specified, return a single list
        of nodes in a shortest path from the source to the target.

        If only the source is specified, return a dictionary keyed by
        targets with a list of nodes in a shortest path from the source
        to one of the targets.

        If only the target is specified, return a dictionary keyed by
        sources with a list of nodes in a shortest path from one of the
        sources to the target.

        If neither the source nor target are specified return a dictionary
        of dictionaries with path[source][target]=[list of nodes in path].

    Examples
    --------
    >>> G = nx.path_graph(5)
    >>> print(nx.shortest_path(G, source=0, target=4))
    [0, 1, 2, 3, 4]
    >>> p = nx.shortest_path(G, source=0) # target not specified
    >>> p[4]
    [0, 1, 2, 3, 4]
    >>> p = nx.shortest_path(G, target=4) # source not specified
    >>> p[0]
    [0, 1, 2, 3, 4]
    >>> p = nx.shortest_path(G) # source, target not specified
    >>> p[0][4]
    [0, 1, 2, 3, 4]

    Notes
    -----
    There may be more than one shortest path between a source and target.
    This returns only one of them.

    See Also
    --------
    all_pairs_shortest_path()
    all_pairs_dijkstra_path()
    single_source_shortest_path()
    single_source_dijkstra_path()
    """
    if source is None:
        if target is None:
            # Find paths between all pairs.
            if weight is None:
                paths = nx.all_pairs_shortest_path(G)
            else:
                paths = nx.all_pairs_dijkstra_path(G, weight=weight)
        else:
            # Find paths from all nodes co-accessible to the target.
            with nx.utils.reversed(G):
                if weight is None:
                    paths = nx.single_source_shortest_path(G, target)
                else:
                    paths = nx.single_source_dijkstra_path(G,
                                                           target,
                                                           weight=weight)
                # Now flip the paths so they go from a source to the target.
                for target in paths:
                    paths[target] = list(reversed(paths[target]))

    else:
        if target is None:
            # Find paths to all nodes accessible from the source.
            if weight is None:
                paths = nx.single_source_shortest_path(G, source)
            else:
                paths = nx.single_source_dijkstra_path(G,
                                                       source,
                                                       weight=weight)
        else:
            # Find shortest source-target path.
            if weight is None:
                paths = nx.bidirectional_shortest_path(G, source, target)
            else:
                paths = nx.dijkstra_path(G, source, target, weight)

    return paths
Example #19
0
def shortest_path_length(G, source=None, target=None, weight=None):
    """Compute shortest path lengths in the graph.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
        Starting node for path.
        If not specified, compute shortest path lengths using all nodes as
        source nodes.

    target : node, optional
        Ending node for path.
        If not specified, compute shortest path lengths using all nodes as
        target nodes.

    weight : None or string, optional (default = None)
        If None, every edge has weight/distance/cost 1.
        If a string, use this edge attribute as the edge weight.
        Any edge attribute not present defaults to 1.

    Returns
    -------
    length: int or iterator
        If the source and target are both specified, return the length of
        the shortest path from the source to the target.

        If only the source is specified, return a tuple
        (target, shortest path length) iterator, where shortest path lengths
        are the lengths of the shortest path from the source to one of the
        targets.

        If only the target is specified, return a tuple
        (source, shortest path length) iterator, where shortest path lengths
        are the lengths of the shortest path from one of the sources
        to the target.

        If neither the source nor target are specified, return a
        (source, dictionary) iterator with dictionary keyed by target and
        shortest path length as the key value.

    Raises
    ------
    NetworkXNoPath
        If no path exists between source and target.

    Examples
    --------
    >>> G = nx.path_graph(5)
    >>> nx.shortest_path_length(G, source=0, target=4)
    4
    >>> p = nx.shortest_path_length(G, source=0) # target not specified
    >>> dict(p)[4]
    4
    >>> p = nx.shortest_path_length(G, target=4) # source not specified
    >>> dict(p)[0]
    4
    >>> p = nx.shortest_path_length(G) # source,target not specified
    >>> dict(p)[0][4]
    4

    Notes
    -----
    The length of the path is always 1 less than the number of nodes involved
    in the path since the length measures the number of edges followed.

    For digraphs this returns the shortest directed path length. To find path
    lengths in the reverse direction use G.reverse(copy=False) first to flip
    the edge orientation.

    See Also
    --------
    all_pairs_shortest_path_length()
    all_pairs_dijkstra_path_length()
    single_source_shortest_path_length()
    single_source_dijkstra_path_length()

    """
    if source is None:
        if target is None:
            # Find paths between all pairs.
            if weight is None:
                paths = nx.all_pairs_shortest_path_length(G)
            else:
                paths = nx.all_pairs_dijkstra_path_length(G, weight=weight)
        else:
            # Find paths from all nodes co-accessible to the target.
            with nx.utils.reversed(G):
                if weight is None:
                    # We need to exhaust the iterator as Graph needs
                    # to be reversed.
                    path_length = nx.single_source_shortest_path_length
                    paths = list(path_length(G, target))
                else:
                    path_length = nx.single_source_dijkstra_path_length
                    paths = path_length(G, target, weight=weight)
    else:
        if source not in G:
            raise nx.NodeNotFound("Source {} not in G".format(source))

        if target is None:
            # Find paths to all nodes accessible from the source.
            if weight is None:
                paths = nx.single_source_shortest_path_length(G, source)
            else:
                paths = nx.single_source_dijkstra_path_length(G,
                                                              source,
                                                              weight=weight)
        else:
            # Find shortest source-target path.
            if weight is None:
                p = nx.bidirectional_shortest_path(G, source, target)
                paths = len(p) - 1
            else:
                paths = nx.dijkstra_path_length(G, source, target, weight)
    return paths
Example #20
0
def shortest_path(G, source=None, target=None, weight=None):
    """Compute shortest paths in the graph.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
       Starting node for path.
       If not specified compute shortest paths for all connected node pairs.

    target : node, optional
       Ending node for path.
       If not specified compute shortest paths for every node reachable
       from the source.

    weight : None or string, optional (default = None)
       If None, every edge has weight/distance/cost 1.
       If a string, use this edge attribute as the edge weight.
       Any edge attribute not present defaults to 1.

    Returns
    -------
    path: list or dictionary
        If the source and target are both specified return a single list
        of nodes in a shortest path.
        If only the source is specified return a dictionary keyed by
        targets with a list of nodes in a shortest path.
        If neither the source or target is specified return a dictionary
        of dictionaries with path[source][target]=[list of nodes in path].

    Examples
    --------
    >>> G=nx.path_graph(5)
    >>> print(nx.shortest_path(G,source=0,target=4))
    [0, 1, 2, 3, 4]
    >>> p=nx.shortest_path(G,source=0) # target not specified
    >>> p[4]
    [0, 1, 2, 3, 4]
    >>> p=nx.shortest_path(G) # source,target not specified
    >>> p[0][4]
    [0, 1, 2, 3, 4]

    Notes
    -----
    There may be more than one shortest path between a source and target.
    This returns only one of them.

    For digraphs this returns a shortest directed path.
    To find paths in the reverse direction first use G.reverse(copy=False)
    to flip the edge orientation.

    See Also
    --------
    all_pairs_shortest_path()
    all_pairs_dijkstra_path()
    single_source_shortest_path()
    single_source_dijkstra_path()
    """
    if source is None:
        if target is None:
            if weight is None:
                paths=nx.all_pairs_shortest_path(G)
            else:
                paths=nx.all_pairs_dijkstra_path(G,weight=weight)
        else:
            raise nx.NetworkXError(\
                "Target given but no source specified.")
    else: # source specified
        if target is None:
            if weight is None:
                paths=nx.single_source_shortest_path(G,source)
            else:
                paths=nx.single_source_dijkstra_path(G,source,weight=weight)
        else:
            # shortest source-target path
            if weight is None:
                paths=nx.bidirectional_shortest_path(G,source,target)
            else:
                paths=nx.dijkstra_path(G,source,target,weight)

    return paths
Example #21
0
 def calculate_longest_road(self, board):
     # Clear the list of roads for each player
     for player in self.players:
         player.roads = []
     # Add all the roads for each player
     for a, b in board.adjacency_iter():
         for c, d in b.items():
             if board[a][c]['object'].player != 0 and (a, c) not in board[a][c]['object'].player.roads:
                 board[a][c]['object'].player.roads.append((a, c))
     # Create the road graph for each player
     for player in self.players:
         player.road_graph = nx.Graph()
         counter = 0
         for road in player.roads:
             if road[0].player != 0 and road[0].player != player:
                 player.road_graph.add_node(counter)
                 player.road_graph.add_node(road[1])
                 counter += 1
             elif road[1].player != 0 and road[1].player != player:
                 player.road_graph.add_node(road[0])
                 player.road_graph.add_node(counter)
                 player.road_graph.add_edge(road[0], counter)
                 counter += 1
             else:
                 player.road_graph.add_node(road[0])
                 player.road_graph.add_node(road[1])
                 player.road_graph.add_edge(road[0], road[1])
         all_paths = []
         for node1, connected_to1 in player.road_graph.adjacency_iter():
             for node2, connected_to2 in player.road_graph.adjacency_iter():
                 if node1 != node2 and nx.bidirectional_shortest_path(player.road_graph, node1, node2):
                     for path in nx.all_simple_paths(player.road_graph, node1, node2):
                         all_paths.append(path)
         if not len(all_paths):
             break
         players_longest_path = all_paths[0]
         for each in all_paths:
             if len(each) > players_longest_path:
                 players_longest_path = each
         player.longest_length = len(players_longest_path)
     longest_path = 0
     longest_path_players = []
     for player in self.players:
         if player.longest_length > longest_path:
             longest_path_player = [player]
             longest_path = player.longest_length
         elif player.longest_length == longest_path:
             longest_path_players.append(player)
             longest_path = player.longest_length
         else:
             continue
     if longest_path >= 5:
         if len(longest_path_players) == 1:
             longest_path_player = longest_path_players[0]
             longest_path = longest_path_player.longest_length
             self.longest_length_history.append(longest_path_player)
             self.longest_length_length = longest_path
         else:
             self.longest_length_history.reverse()
             for each in self.longest_length_history:
                 if each in longest_path_players:
                     longest_path_player = each
                     longest_path = longest_path_player.longest_length
                     self.longest_length_history.append(longest_path_player)
                     self.longest_length_length = longest_path
                     break
                 else:
                     continue
     for player in self.players:
         player.longest_road = 0
         if self.longest_length_history:  
             if self.longest_length_history[-1] == player:
                 player.longest_road = 2
Example #22
0
def shortest_path(G, source=None, target=None, weight=None):
    """Compute shortest paths in the graph.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
       Starting node for path.
       If not specified compute shortest paths for all connected node pairs.

    target : node, optional
       Ending node for path.
       If not specified compute shortest paths for every node reachable
       from the source.

    weight : None or string, optional (default = None)
       If None, every edge has weight/distance/cost 1.
       If a string, use this edge attribute as the edge weight.
       Any edge attribute not present defaults to 1.

    Returns
    -------
    path: list or dictionary
        If the source and target are both specified return a single list
        of nodes in a shortest path.
        If only the source is specified return a dictionary keyed by
        targets with a list of nodes in a shortest path.
        If neither the source or target is specified return a dictionary
        of dictionaries with path[source][target]=[list of nodes in path].

    Examples
    --------
    >>> G=nx.path_graph(5)
    >>> print(nx.shortest_path(G,source=0,target=4))
    [0, 1, 2, 3, 4]
    >>> p=nx.shortest_path(G,source=0) # target not specified
    >>> p[4]
    [0, 1, 2, 3, 4]
    >>> p=nx.shortest_path(G) # source,target not specified
    >>> p[0][4]
    [0, 1, 2, 3, 4]

    Notes
    -----
    There may be more than one shortest path between a source and target.
    This returns only one of them.

    For digraphs this returns a shortest directed path.
    To find paths in the reverse direction first use G.reverse(copy=False)
    to flip the edge orientation.

    See Also
    --------
    all_pairs_shortest_path()
    all_pairs_dijkstra_path()
    single_source_shortest_path()
    single_source_dijkstra_path()
    """
    if source is None:
        if target is None:
            if weight is None:
                paths=nx.all_pairs_shortest_path(G)
            else:
                paths=nx.all_pairs_dijkstra_path(G,weight=weight)
        else:
            raise nx.NetworkXError(\
                "Target given but no source specified.")
    else: # source specified
        if target is None:
            if weight is None:
                paths=nx.single_source_shortest_path(G,source)
            else:
                paths=nx.single_source_dijkstra_path(G,source,weight=weight)
        else:
            # shortest source-target path
            if weight is None:
                paths=nx.bidirectional_shortest_path(G,source,target)
            else:
                paths=nx.dijkstra_path(G,source,target,weight)

    return paths
Example #23
0
def shortest_path_length(G, source=None, target=None, weight=None):
    """Compute shortest path lengths in the graph.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
        Starting node for path.
        If not specified, compute shortest path lengths using all nodes as
        source nodes.

    target : node, optional
        Ending node for path.
        If not specified, compute shortest path lengths using all nodes as
        target nodes.

    weight : None or string, optional (default = None)
        If None, every edge has weight/distance/cost 1.
        If a string, use this edge attribute as the edge weight.
        Any edge attribute not present defaults to 1.

    Returns
    -------
    length: int or iterator
        If the source and target are both specified, return the length of
        the shortest path from the source to the target.

        If only the source is specified, return a tuple
        (target, shortest path length) iterator, where shortest path lengths
        are the lengths of the shortest path from the source to one of the
        targets.

        If only the target is specified, return a tuple
        (source, shortest path length) iterator, where shortest path lengths
        are the lengths of the shortest path from one of the sources
        to the target.

        If neither the source nor target are specified, return a
        (source, dictionary) iterator with dictionary keyed by target and
        shortest path length as the key value.

    Raises
    ------
    NetworkXNoPath
        If no path exists between source and target.

    Examples
    --------
    >>> G = nx.path_graph(5)
    >>> nx.shortest_path_length(G, source=0, target=4)
    4
    >>> p = nx.shortest_path_length(G, source=0) # target not specified
    >>> dict(p)[4]
    4
    >>> p = nx.shortest_path_length(G, target=4) # source not specified
    >>> dict(p)[0]
    4
    >>> p = nx.shortest_path_length(G) # source,target not specified
    >>> dict(p)[0][4]
    4

    Notes
    -----
    The length of the path is always 1 less than the number of nodes involved
    in the path since the length measures the number of edges followed.

    For digraphs this returns the shortest directed path length. To find path
    lengths in the reverse direction use G.reverse(copy=False) first to flip
    the edge orientation.

    See Also
    --------
    all_pairs_shortest_path_length()
    all_pairs_dijkstra_path_length()
    single_source_shortest_path_length()
    single_source_dijkstra_path_length()

    """
    if source is None:
        if target is None:
            # Find paths between all pairs.
            if weight is None:
                paths = nx.all_pairs_shortest_path_length(G)
            else:
                paths = nx.all_pairs_dijkstra_path_length(G, weight=weight)
        else:
            # Find paths from all nodes co-accessible to the target.
            with nx.utils.reversed(G):
                if weight is None:
                    # We need to exhaust the iterator as Graph needs
                    # to be reversed.
                    path_length = nx.single_source_shortest_path_length
                    paths = list(path_length(G, target))
                else:
                    path_length = nx.single_source_dijkstra_path_length
                    paths = path_length(G, target, weight=weight)
    else:
        if source not in G:
            raise nx.NodeNotFound("Source {} not in G".format(source));

        if target is None:
            # Find paths to all nodes accessible from the source.
            if weight is None:
                paths = nx.single_source_shortest_path_length(G, source)
            else:
                paths = nx.single_source_dijkstra_path_length(G, source,
                                                              weight=weight)
        else:
            # Find shortest source-target path.
            if weight is None:
                p = nx.bidirectional_shortest_path(G, source, target)
                paths = len(p)-1
            else:
                paths = nx.dijkstra_path_length(G, source, target, weight)
    return paths
Example #24
0
def shortest_path(G, source=None, target=None, weight=None, method="dijkstra"):
    """Compute shortest paths in the graph.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
        Starting node for path. If not specified, compute shortest
        paths for each possible starting node.

    target : node, optional
        Ending node for path. If not specified, compute shortest
        paths to all possible nodes.

    weight : None or string, optional (default = None)
        If None, every edge has weight/distance/cost 1.
        If a string, use this edge attribute as the edge weight.
        Any edge attribute not present defaults to 1.

    method : string, optional (default = 'dijkstra')
        The algorithm to use to compute the path.
        Supported options: 'dijkstra', 'bellman-ford'.
        Other inputs produce a ValueError.
        If `weight` is None, unweighted graph methods are used, and this
        suggestion is ignored.

    Returns
    -------
    path: list or dictionary
        All returned paths include both the source and target in the path.

        If the source and target are both specified, return a single list
        of nodes in a shortest path from the source to the target.

        If only the source is specified, return a dictionary keyed by
        targets with a list of nodes in a shortest path from the source
        to one of the targets.

        If only the target is specified, return a dictionary keyed by
        sources with a list of nodes in a shortest path from one of the
        sources to the target.

        If neither the source nor target are specified return a dictionary
        of dictionaries with path[source][target]=[list of nodes in path].

    Raises
    ------
    NodeNotFound
        If `source` is not in `G`.

    ValueError
        If `method` is not among the supported options.

    Examples
    --------
    >>> G = nx.path_graph(5)
    >>> print(nx.shortest_path(G, source=0, target=4))
    [0, 1, 2, 3, 4]
    >>> p = nx.shortest_path(G, source=0)  # target not specified
    >>> p[4]
    [0, 1, 2, 3, 4]
    >>> p = nx.shortest_path(G, target=4)  # source not specified
    >>> p[0]
    [0, 1, 2, 3, 4]
    >>> p = nx.shortest_path(G)  # source, target not specified
    >>> p[0][4]
    [0, 1, 2, 3, 4]

    Notes
    -----
    There may be more than one shortest path between a source and target.
    This returns only one of them.

    See Also
    --------
    all_pairs_shortest_path
    all_pairs_dijkstra_path
    all_pairs_bellman_ford_path
    single_source_shortest_path
    single_source_dijkstra_path
    single_source_bellman_ford_path
    """
    if method not in ("dijkstra", "bellman-ford"):
        # so we don't need to check in each branch later
        raise ValueError(f"method not supported: {method}")
    method = "unweighted" if weight is None else method
    if source is None:
        if target is None:
            # Find paths between all pairs.
            if method == "unweighted":
                paths = dict(nx.all_pairs_shortest_path(G))
            elif method == "dijkstra":
                paths = dict(nx.all_pairs_dijkstra_path(G, weight=weight))
            else:  # method == 'bellman-ford':
                paths = dict(nx.all_pairs_bellman_ford_path(G, weight=weight))
        else:
            # Find paths from all nodes co-accessible to the target.
            if G.is_directed():
                G = G.reverse(copy=False)
            if method == "unweighted":
                paths = nx.single_source_shortest_path(G, target)
            elif method == "dijkstra":
                paths = nx.single_source_dijkstra_path(G, target, weight=weight)
            else:  # method == 'bellman-ford':
                paths = nx.single_source_bellman_ford_path(G, target, weight=weight)
            # Now flip the paths so they go from a source to the target.
            for target in paths:
                paths[target] = list(reversed(paths[target]))
    else:
        if target is None:
            # Find paths to all nodes accessible from the source.
            if method == "unweighted":
                paths = nx.single_source_shortest_path(G, source)
            elif method == "dijkstra":
                paths = nx.single_source_dijkstra_path(G, source, weight=weight)
            else:  # method == 'bellman-ford':
                paths = nx.single_source_bellman_ford_path(G, source, weight=weight)
        else:
            # Find shortest source-target path.
            if method == "unweighted":
                paths = nx.bidirectional_shortest_path(G, source, target)
            elif method == "dijkstra":
                _, paths = nx.bidirectional_dijkstra(G, source, target, weight)
            else:  # method == 'bellman-ford':
                paths = nx.bellman_ford_path(G, source, target, weight)
    return paths
Example #25
0
def shortest_path_length(G,source=None,target=None,weighted=False):
    """Compute shortest path lengths in the graph.
    
    This function can compute the single source shortest path
    lengths by specifying only the source or all pairs shortest
    path lengths by specifying neither the source or target.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
       Starting node for path.  
       If not specified compute shortest pats lenghts for all 
       connected node pairs.

    target : node, optional 
       Ending node for path.  
       If not specified compute shortest path lenghts for every 
       node reachable from the source.

    weighted : bool, optional
       If True consider weighted edges when finding shortest path length.

    Returns
    -------
    length : number, or container of numbers
        If the source and target are both specified return a
        single number for the shortest path.
        If only the source is specified return a dictionary keyed by
        targets with a the shortest path as keys.
        If neither the source or target is specified return a dictionary 
        of dictionaries with length[source][target]=value.

    Raises
    ------
    NetworkXError
        If no path exists between source and target.

    Examples
    --------
    >>> G=nx.path_graph(5)
    >>> print nx.shortest_path_length(G,source=0,target=4)
    4
    >>> p=nx.shortest_path_length(G,source=0) # target not specified
    >>> p[4]
    4
    >>> p=nx.shortest_path_length(G) # source,target not specified
    >>> p[0][4]
    4

    Notes
    -----
    If weighted=True and the graph has no 'weight' edge attribute
    the value 1 will be used.

    For digraphs this returns the shortest directed path.
    To find path lengths in the reverse direction use G.reverse(copy=False)
    first to flip the edge orientation.
    """
    if source is None:
        if target is None:
            if weighted:
                paths=nx.all_pairs_dijkstra_path_length(G)
            else:
                paths=nx.all_pairs_shortest_path_length(G)
        else:
            raise nx.NetworkXError(\
                "Target given but no source specified.")
    else: # source specified
        if target is None:
            if weighted:
                paths=nx.single_source_dijkstra_path_length(G,source)
            else:
                paths=nx.single_source_shortest_path_length(G,source)
        else:
            # shortest source-target path
            if weighted:
                paths=nx.dijkstra_path_length(G,source,target)
            else:
                p=nx.bidirectional_shortest_path(G,source,target)
                if p is False:
                    raise nx.NetworkXError(\
                        "No path from %s to %s."%(source,target))
                paths=len(p)-1
    return paths
def ford_fulkerson_flow_and_auxiliary(G, s, t, capacity='capacity'):
    """Find a maximum single-commodity flow using the Ford-Fulkerson
    algorithm.
    
    This function returns both the value of the maximum flow and the 
    auxiliary network resulting after finding the maximum flow, which
    is also named residual network in the literature. The 
    auxiliary network has edges with capacity equal to the capacity 
    of the edge in the original network minus the flow that went 
    throught that edge. Notice that it can happen that a flow 
    from v to u is allowed in the auxiliary network, though disallowed 
    in the original network. A dictionary with infinite capacity edges 
    can be found as an attribute of the auxiliary network.

    Parameters
    ----------
    G : NetworkX graph
        Edges of the graph are expected to have an attribute called
        'capacity'. If this attribute is not present, the edge is
        considered to have infinite capacity.

    s : node
        Source node for the flow.

    t : node
        Sink node for the flow.

    capacity: string
        Edges of the graph G are expected to have an attribute capacity
        that indicates how much flow the edge can support. If this
        attribute is not present, the edge is considered to have
        infinite capacity. Default value: 'capacity'.

    Returns
    -------
    flow_value : integer, float
        Value of the maximum flow, i.e., net outflow from the source.

    auxiliary : DiGraph
        Residual/auxiliary network after finding the maximum flow. 
        A dictionary with infinite capacity edges can be found as 
        an attribute of this network: auxiliary.graph['inf_capacity_flows']

    Raises
    ------
    NetworkXError
        The algorithm does not support MultiGraph and MultiDiGraph. If
        the input graph is an instance of one of these two classes, a
        NetworkXError is raised.

    NetworkXUnbounded
        If the graph has a path of infinite capacity, the value of a 
        feasible flow on the graph is unbounded above and the function
        raises a NetworkXUnbounded.

    Notes
    -----
    This algorithm uses Edmonds-Karp-Dinitz path selection rule which
    guarantees a running time of `O(nm^2)` for `n` nodes and `m` edges.

    Examples
    --------
    >>> import networkx as nx
    >>> G = nx.DiGraph()
    >>> G.add_edge('x','a', capacity=3.0)
    >>> G.add_edge('x','b', capacity=1.0)
    >>> G.add_edge('a','c', capacity=3.0)
    >>> G.add_edge('b','c', capacity=5.0)
    >>> G.add_edge('b','d', capacity=4.0)
    >>> G.add_edge('d','e', capacity=2.0)
    >>> G.add_edge('c','y', capacity=2.0)
    >>> G.add_edge('e','y', capacity=3.0)
    >>> flow, auxiliary = nx.ford_fulkerson_flow_and_auxiliary(G, 'x', 'y')
    >>> flow
    3.0
    >>> # A dictionary with infinite capacity flows can be found as an
    >>> # attribute of the auxiliary network
    >>> inf_capacity_flows = auxiliary.graph['inf_capacity_flows']

    """
    if G.is_multigraph():
        raise nx.NetworkXError(
                'MultiGraph and MultiDiGraph not supported (yet).')

    if s not in G:
        raise nx.NetworkXError('node %s not in graph' % str(s))
    if t not in G:
        raise nx.NetworkXError('node %s not in graph' % str(t))

    auxiliary = _create_auxiliary_digraph(G, capacity=capacity)
    inf_capacity_flows = auxiliary.graph['inf_capacity_flows']

    flow_value = 0   # Initial feasible flow.

    # As long as there is an (s, t)-path in the auxiliary digraph, find
    # the shortest (with respect to the number of arcs) such path and
    # augment the flow on this path.
    while True:
        try:
            path_nodes = nx.bidirectional_shortest_path(auxiliary, s, t)
        except nx.NetworkXNoPath:
            break

        # Get the list of edges in the shortest path.
        path_edges = list(zip(path_nodes[:-1], path_nodes[1:]))

        # Find the minimum capacity of an edge in the path.
        try:
            path_capacity = min([auxiliary[u][v][capacity]
                                for u, v in path_edges
                                if capacity in auxiliary[u][v]])
        except ValueError: 
            # path of infinite capacity implies no max flow
            raise nx.NetworkXUnbounded(
                    "Infinite capacity path, flow unbounded above.")
        
        flow_value += path_capacity

        # Augment the flow along the path.
        for u, v in path_edges:
            edge_attr = auxiliary[u][v]
            if capacity in edge_attr:
                edge_attr[capacity] -= path_capacity
                if edge_attr[capacity] == 0:
                    auxiliary.remove_edge(u, v)
            else:
                inf_capacity_flows[(u, v)] += path_capacity

            if auxiliary.has_edge(v, u):
                if capacity in auxiliary[v][u]:
                    auxiliary[v][u][capacity] += path_capacity
            else:
                auxiliary.add_edge(v, u, {capacity: path_capacity})
    
    auxiliary.graph['inf_capacity_flows'] = inf_capacity_flows
    return flow_value, auxiliary
Example #27
0
def ford_fulkerson(G, s, t, capacity="capacity"):
    """Find a maximum single-commodity flow using the Ford-Fulkerson
    algorithm.
    
    This algorithm uses Edmonds-Karp-Dinitz path selection rule which
    guarantees a running time of O(nm^2) for n nodes and m edges.


    Parameters
    ----------
    G : NetworkX nxgraph
        Edges of the nxgraph are expected to have an attribute called
        'capacity'. If this attribute is not present, the edge is
        considered to have infinite capacity.

    s : node
        Source node for the flow.

    t : node
        Sink node for the flow.

    capacity: string
        Edges of the nxgraph G are expected to have an attribute capacity
        that indicates how much flow the edge can support. If this
        attribute is not present, the edge is considered to have
        infinite capacity. Default value: 'capacity'.

    Returns
    -------
    flow_value : integer, float
        Value of the maximum flow, i.e., net outflow from the source.

    flow_dict : dictionary
        Dictionary of dictionaries keyed by nodes such that
        flow_dict[u][v] is the flow edge (u, v).

    Raises
    ------
    NetworkXError
        The algorithm does not support MultiGraph and MultiDiGraph. If
        the input nxgraph is an instance of one of these two classes, a
        NetworkXError is raised.

    NetworkXUnbounded
        If the nxgraph has a path of infinite capacity, the value of a
        feasible flow on the nxgraph is unbounded above and the function
        raises a NetworkXUnbounded.

    Examples
    --------
    >>> import networkx as nx
    >>> G = nx.DiGraph()
    >>> G.add_edge('x','a', capacity=3.0)
    >>> G.add_edge('x','b', capacity=1.0)
    >>> G.add_edge('a','c', capacity=3.0)
    >>> G.add_edge('b','c', capacity=5.0)
    >>> G.add_edge('b','d', capacity=4.0)
    >>> G.add_edge('d','e', capacity=2.0)
    >>> G.add_edge('c','y', capacity=2.0)
    >>> G.add_edge('e','y', capacity=3.0)
    >>> flow, F = nx.ford_fulkerson(G, 'x', 'y')
    >>> flow
    3.0
    """
    if G.is_multigraph():
        raise nx.NetworkXError("MultiGraph and MultiDiGraph not supported (yet).")

    if s not in G:
        raise nx.NetworkXError("node %s not in nxgraph" % str(s))
    if t not in G:
        raise nx.NetworkXError("node %s not in nxgraph" % str(t))

    auxiliary, inf_capacity_flows = _create_auxiliary_digraph(G, capacity=capacity)
    flow_value = 0  # Initial feasible flow.

    # As long as there is an (s, t)-path in the auxiliary digraph, find
    # the shortest (with respect to the number of arcs) such path and
    # augment the flow on this path.
    while True:
        try:
            path_nodes = nx.bidirectional_shortest_path(auxiliary, s, t)
        except nx.NetworkXNoPath:
            break

        # Get the list of edges in the shortest path.
        path_edges = list(zip(path_nodes[:-1], path_nodes[1:]))

        # Find the minimum capacity of an edge in the path.
        try:
            path_capacity = min([auxiliary[u][v][capacity] for u, v in path_edges if capacity in auxiliary[u][v]])
        except ValueError:
            # path of infinite capacity implies no max flow
            raise nx.NetworkXUnbounded("Infinite capacity path, flow unbounded above.")

        flow_value += path_capacity

        # Augment the flow along the path.
        for u, v in path_edges:
            edge_attr = auxiliary[u][v]
            if capacity in edge_attr:
                edge_attr[capacity] -= path_capacity
                if edge_attr[capacity] == 0:
                    auxiliary.remove_edge(u, v)
            else:
                inf_capacity_flows[(u, v)] += path_capacity

            if auxiliary.has_edge(v, u):
                if capacity in auxiliary[v][u]:
                    auxiliary[v][u][capacity] += path_capacity
            else:
                auxiliary.add_edge(v, u, {capacity: path_capacity})

    flow_dict = _create_flow_dict(G, auxiliary, inf_capacity_flows, capacity=capacity)
    return flow_value, flow_dict
Example #28
0
    def detect(self):
        """detect the source with GSBA.
        Returns:
            @rtype:int
            the detected source
        """
        ''' 
        这是什么时候调用的?这是公式需要,对别的来说,就不是这个了。所有对于贪心是有两个

        先验的,一个是要谣言中心性,一个是其他。
        我们要加我们的就是加一个先验的,比如覆盖的操作,模仿其谣言定位方式,自己写一个
        然后作为先验,放在先验中。

        '''
        self.reset_centrality()
        self.prior_detector.set_data(self.data)
        self.prior_detector.detect()
        self.prior = nx.get_node_attributes(self.subgraph, 'centrality')

        # print('先验检测器是什么?')
        # print(self.prior)

        self.reset_centrality()
        rc = rumor_center.RumorCenter()
        rc.set_data(self.data)
        rc.detect()
        rumor_centralities = nx.get_node_attributes(self.subgraph,
                                                    'centrality')

        self.reset_centrality()

        # 获取边界点.
        infected_nodes = set(self.subgraph.nodes())
        n = len(infected_nodes)
        bound_list = []
        for node in infected_nodes:
            neig = nx.neighbors(self.data.graph, node)
            infect_ne = len([x for x in neig if x in infected_nodes])
            if infect_ne == 1:
                bound_list.append(node)
            print('bound_list')
            print(bound_list)

        # 获取边界点.
        infected_nodes = set(self.subgraph.nodes())
        n = len(infected_nodes)
        # infected_nodes_new = set(simple_subgraph.nodes())
        # n = len(infected_nodes_new)
        posterior = {}
        included = set()
        neighbours = set()
        weights = self.data.weights
        for v in infected_nodes:
            path_list = []
            path_list.append(v)
            for bound_node in bound_list:
                path = nx.bidirectional_shortest_path(self.subgraph,
                                                      source=v,
                                                      target=bound_node)
                print('path')
                print(path)
                path_list.extend(path)
            simple_subgraph = self.data.graph.subgraph(set(path_list))

            print('开始寻找likehood的')
            """find the approximate upper bound by greedy searching"""
            included.clear()
            neighbours.clear()
            included.add(v)
            neighbours.add(v)
            likelihood = 1
            w = {}  # effective propagation probabilities: node->w
            w_key_sorted = blist()
            w[v] = 1
            w_key_sorted.append(v)
            while len(included) < n and len(w_key_sorted) > 0:
                # print('邻居用来计算所谓的neighbours')
                # print(neighbours)
                w_sum = sum([w[j] for j in neighbours])
                u = w_key_sorted.pop(
                )  # pop out the last element from w_key_sorted with the largest w
                likelihood += w[u] / w_sum
                # print('分母是?')
                # print(w_sum)
                # print('likelihood')
                # print(likelihood)
                included.add(u)
                neighbours.remove(u)
                new = nx.neighbors(simple_subgraph, u)
                # print('new也就是在总图中的邻居')
                # print(new)
                for h in new:
                    # print('遍历到某个邻居')
                    # print(h)
                    if h in included:
                        continue
                    neighbours.add(h)
                    # compute w for h
                    w_h2u = weights[self.data.node2index[u],
                                    self.data.node2index[h]]
                    # w_h2u = weights[self.data.node2index[u]][self.data.node2index[h]]
                    if h in w.keys():
                        # print('------')
                        # print(w[h])
                        # print(w_h2u)
                        w[h] = 1 - (1 - w[h]) * (1 - w_h2u)
                        # print('w[h],,,,h在keys')
                        # print(w[h])
                    else:
                        # print('h不在keys')
                        w[h] = w_h2u
                        # print(w[h])

                    # print('w是什么')
                    # print(w)
                    # h_neighbor = nx.neighbors(self.data.graph, h)
                    # w_h = 1
                    # for be in included.intersection(h_neighbor):
                    #     w_h *= 1 - self.data.get_weight(h, be)
                    # w[h] = 1 - w_h
                    """insert h into w_key_sorted, ranking by w from small to large"""
                    if h in infected_nodes:
                        # print('开始排序了')
                        if h in w_key_sorted:
                            w_key_sorted.remove(h)  # remove the old w[h]
                        k = 0

                        while k < len(w_key_sorted):
                            if w[w_key_sorted[k]] > w[h]:
                                break
                            k += 1
                        # print(w_key_sorted)
                        w_key_sorted.insert(k, h)  # 安排降序加入,就是排列可能性加入,安排顺序插入进去
                        # print('w_key_sorted')
                        # print(w_key_sorted)

                        # w_key_sorted[k:k] = [h]
            # print('每次开始的是那个节点呢?')
            # print(v)
            # print('每一个的可能性是likehood')
            # print(likelihood)
            posterior[v] = (decimal.Decimal(
                decimal.Decimal(likelihood) * self.prior[v] *
                rumor_centralities[v]))

        # print('w_key_sorted')
        # print(w_key_sorted)
        #
        # print('------------')
        # print(coverage_centralities)
        # print('看下这里的posterior')
        # print(posterior)
        nx.set_node_attributes(self.subgraph, 'centrality', posterior)
        return self.sort_nodes_by_centrality()
Example #29
0
def shortest_path(G, source=None, target=None, weight=None):
    """Compute shortest paths in the graph.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
        Starting node for path.
        If not specified, compute shortest paths using all nodes as source nodes.

    target : node, optional
        Ending node for path.
        If not specified, compute shortest paths using all nodes as target nodes.

    weight : None or string, optional (default = None)
        If None, every edge has weight/distance/cost 1.
        If a string, use this edge attribute as the edge weight.
        Any edge attribute not present defaults to 1.

    Returns
    -------
    path: list or dictionary
        All returned paths include both the source and target in the path.

        If the source and target are both specified, return a single list
        of nodes in a shortest path from the source to the target.

        If only the source is specified, return a dictionary keyed by
        targets with a list of nodes in a shortest path from the source
        to one of the targets.

        If only the target is specified, return a dictionary keyed by
        sources with a list of nodes in a shortest path from one of the
        sources to the target.

        If neither the source nor target are specified return a dictionary
        of dictionaries with path[source][target]=[list of nodes in path].

    Examples
    --------
    >>> G=nx.path_graph(5)
    >>> print(nx.shortest_path(G,source=0,target=4))
    [0, 1, 2, 3, 4]
    >>> p=nx.shortest_path(G,source=0) # target not specified
    >>> p[4]
    [0, 1, 2, 3, 4]
    >>> p=nx.shortest_path(G,target=4) # source not specified
    >>> p[0]
    [0, 1, 2, 3, 4]
    >>> p=nx.shortest_path(G) # source,target not specified
    >>> p[0][4]
    [0, 1, 2, 3, 4]

    Notes
    -----
    There may be more than one shortest path between a source and target.
    This returns only one of them.

    For digraphs this returns a shortest directed path. To find paths in the
    reverse direction first use G.reverse(copy=False) to flip the edge
    orientation.

    See Also
    --------
    all_pairs_shortest_path()
    all_pairs_dijkstra_path()
    single_source_shortest_path()
    single_source_dijkstra_path()
    """
    if source is None:
        if target is None:
            ## Find paths between all pairs.
            if weight is None:
                paths=nx.all_pairs_shortest_path(G)
            else:
                paths=nx.all_pairs_dijkstra_path(G,weight=weight)
        else:
            ## Find paths from all nodes co-accessible to the target.
            directed = G.is_directed()
            if directed:
               G.reverse(copy=False)

            if weight is None:
                paths=nx.single_source_shortest_path(G,target)
            else:
                paths=nx.single_source_dijkstra_path(G,target,weight=weight)

            # Now flip the paths so they go from a source to the target.
            for target in paths:
                paths[target] = list(reversed(paths[target]))

            if directed:
                G.reverse(copy=False)
    else:
        if target is None:
            ## Find paths to all nodes accessible from the source.
            if weight is None:
                paths=nx.single_source_shortest_path(G,source)
            else:
                paths=nx.single_source_dijkstra_path(G,source,weight=weight)
        else:
            ## Find shortest source-target path.
            if weight is None:
                paths=nx.bidirectional_shortest_path(G,source,target)
            else:
                paths=nx.dijkstra_path(G,source,target,weight)

    return paths
Example #30
0
def shortest_path_length(G, source=None, target=None, weight=None, method="dijkstra"):
    """Compute shortest path lengths in the graph.

    Parameters
    ----------
    G : NetworkX graph

    source : node, optional
        Starting node for path.
        If not specified, compute shortest path lengths using all nodes as
        source nodes.

    target : node, optional
        Ending node for path.
        If not specified, compute shortest path lengths using all nodes as
        target nodes.

    weight : None or string, optional (default = None)
        If None, every edge has weight/distance/cost 1.
        If a string, use this edge attribute as the edge weight.
        Any edge attribute not present defaults to 1.

    method : string, optional (default = 'dijkstra')
        The algorithm to use to compute the path length.
        Supported options: 'dijkstra', 'bellman-ford'.
        Other inputs produce a ValueError.
        If `weight` is None, unweighted graph methods are used, and this
        suggestion is ignored.

    Returns
    -------
    length: int or iterator
        If the source and target are both specified, return the length of
        the shortest path from the source to the target.

        If only the source is specified, return a dict keyed by target
        to the shortest path length from the source to that target.

        If only the target is specified, return a dict keyed by source
        to the shortest path length from that source to the target.

        If neither the source nor target are specified, return an iterator
        over (source, dictionary) where dictionary is keyed by target to
        shortest path length from source to that target.

    Raises
    ------
    NodeNotFound
        If `source` is not in `G`.

    NetworkXNoPath
        If no path exists between source and target.

    ValueError
        If `method` is not among the supported options.

    Examples
    --------
    >>> G = nx.path_graph(5)
    >>> nx.shortest_path_length(G, source=0, target=4)
    4
    >>> p = nx.shortest_path_length(G, source=0)  # target not specified
    >>> p[4]
    4
    >>> p = nx.shortest_path_length(G, target=4)  # source not specified
    >>> p[0]
    4
    >>> p = dict(nx.shortest_path_length(G))  # source,target not specified
    >>> p[0][4]
    4

    Notes
    -----
    The length of the path is always 1 less than the number of nodes involved
    in the path since the length measures the number of edges followed.

    For digraphs this returns the shortest directed path length. To find path
    lengths in the reverse direction use G.reverse(copy=False) first to flip
    the edge orientation.

    See Also
    --------
    all_pairs_shortest_path_length
    all_pairs_dijkstra_path_length
    all_pairs_bellman_ford_path_length
    single_source_shortest_path_length
    single_source_dijkstra_path_length
    single_source_bellman_ford_path_length
    """
    if method not in ("dijkstra", "bellman-ford"):
        # so we don't need to check in each branch later
        raise ValueError(f"method not supported: {method}")
    method = "unweighted" if weight is None else method
    if source is None:
        if target is None:
            # Find paths between all pairs.
            if method == "unweighted":
                paths = nx.all_pairs_shortest_path_length(G)
            elif method == "dijkstra":
                paths = nx.all_pairs_dijkstra_path_length(G, weight=weight)
            else:  # method == 'bellman-ford':
                paths = nx.all_pairs_bellman_ford_path_length(G, weight=weight)
        else:
            # Find paths from all nodes co-accessible to the target.
            if G.is_directed():
                G = G.reverse(copy=False)
            if method == "unweighted":
                path_length = nx.single_source_shortest_path_length
                paths = path_length(G, target)
            elif method == "dijkstra":
                path_length = nx.single_source_dijkstra_path_length
                paths = path_length(G, target, weight=weight)
            else:  # method == 'bellman-ford':
                path_length = nx.single_source_bellman_ford_path_length
                paths = path_length(G, target, weight=weight)
    else:
        if target is None:
            # Find paths to all nodes accessible from the source.
            if method == "unweighted":
                paths = nx.single_source_shortest_path_length(G, source)
            elif method == "dijkstra":
                path_length = nx.single_source_dijkstra_path_length
                paths = path_length(G, source, weight=weight)
            else:  # method == 'bellman-ford':
                path_length = nx.single_source_bellman_ford_path_length
                paths = path_length(G, source, weight=weight)
        else:
            # Find shortest source-target path.
            if method == "unweighted":
                p = nx.bidirectional_shortest_path(G, source, target)
                paths = len(p) - 1
            elif method == "dijkstra":
                paths = nx.dijkstra_path_length(G, source, target, weight)
            else:  # method == 'bellman-ford':
                paths = nx.bellman_ford_path_length(G, source, target, weight)
    return paths