Getting a random simple path between two nodes in a graph - python-3.x

Given the start node and goal node in a graph, I want to find one simple path between these two nodes. I do not want the shortest path, but need any random simple path.
I tried using all_simple_paths from networkx, but this module seems to calculate all the simple paths before returning anything. This takes a long time to run.
Is there a way to find just one simple path?
Also, I would ideally like to make sure this path does not cross any "obstacles". These obstacles are a predefined set of nodes from the same graph. Is there a way to add in this constraint?
PS: I don't necessarily need to use networkx. The code I am writing is in Python.

You could treat this as a min cost network flow problem where your start node wants to send a unit of flow (demand = -1) to your goal node (demand = 1). You can set the edge capacities to 1 and you can set all the edge weights to 0 except for those around "obstacle" nodes. For those obstacle nodes you can set all the edges either coming into or going out of them to have a weight of 1. The algorithm will try to find any arbitrary path using only edges with weight 0, but will use weight 1 edges if no path exists with only weight 0 edges.
See the nx.min_cost_flow function. This function requires you to make your graph a directed graph nx.DiGraph if it's not already.

I managed to solve this problem by using the RRT algorithm. It gives a random path between the source and destination nodes and also avoids obstacles.

Related

Dynamic programming efficient network

Hello I have a dynamic programming related question. How can I compute the shortest path in hops from starting node to ending, with the constrain that the vertices and edges will have an equal or higher predefined value. For example the highest rate of data in a network. Could someone provide some pseudo-code or any thoughts, thank you in advance.
Build new graph from the given network, which does not contain the vertices and edges whose value is less than the predefined value, and from the start node, in the new graph run an algorithm to find the shortest path to the end node, such as BFS, Dijkstra (-Greedy, not Dynamic Programming), Bellman – Ford, etc.

Find shortest paths through predefined set of vertices and edges in arangodb

I need to find shortest paths which should pass through several nodes and edges. Few details:
It should be shortest paths according to weights.
Include set can be ordered and unordered.
Graph size - 50 000 vertices and 450 0000 edges
Is there any way to find paths like this using arangodb?
I've tried K_SHORTEST_PATHS but it is too slow for some cases.
Without a data set, this is tricky to test. Unfortunately, K_SHORTEST_PATHS is the only built-in way to add "weight" to edges, unless you build something yourself. Also, both SHORTEST_PATH methods do not implement PRUNE, which is the best way to speed graph traversal.
My suggestion would be to use a directed graph method (FOR v,e,p IN 1..9 INBOUND x...), implementing both PRUNE and FILTER clauses to reduce the number of hops, and something like COLLECT path = p AGGREGATE weight = SUM(e.weight) to calculate weight.

How can I make curved edges between two nodes in a DiGraph?

I am trying to add curved arrows between two nodes in a DiGraph by using NetworkX library.
The documentation for the function nx.draw_networkx_edges mentions the argument connectionstyle. Setting connectionstyle='arc3, rad = 0.2' should yield curved connectors. But I am unable to reproduce this.
I have also looked into the module matplotlib.patches and call ConnectionStyle as mentioned in https://matplotlib.org/stable/api/_as_gen/matplotlib.patches.ConnectionStyle.html ; but I still get the same visual.
array_of_edges = list(zip(df.start_node, df.end_node, df.weight))
G.add_weighted_edges_from(array_of_edges)
nx.draw_networkx_edges(
G, pos_nodes,
edge_color='#5B174C',
width=df['weight'] / 600,
alpha=0.8,
connectionstyle='arc3,rad=0.2')
This is what I am getting and this is what I require:
https://imgur.com/a/1TcPfY9
I had a similar issue a while back (I wanted to compare two states of the same network). I couldn't work out a solution using networkx so I made my own, the code for which can be found here.
You will have to convert your edge list into a square adjacency matrix, where the absence of a connection is denoted by a NaN, and non-NaN entries are interpreted as edge weights and mapped to edge colors. You can then call the module using
network_line_graph.draw(adjacency_matrix, node_order=None, arc_above=True)
Note that if you don't specify the node order explicitly, the node order is optimised using recursive minimum flow cuts to place strongly connected subnetworks/nodes together (ideally you would minimize total arc length but that gets computationally expensive very quickly).
The API is pretty similar to networkx but if you do have any problems, please raise an issue on the github.

How to collect all chains by using python3

Background:
I'm doing polymer simulation. And I'm trying to use networkx to calculate how many chains in the system. Molecules inside systems are equal to the nodes and bonds equal to the connection between nodes.
What I have tried:
I used networkx.chain_decompostion to calculate the number of the chain.
import networkx as nx
info = nx.chain_decomposition(G)
Issues:
I found it only find the chains which are closed loop, such as A1-A2-A3-A1.
However, there are still many chains are not closed, such as A1-A2-A3.
Is there an easy way to collect both types of the chains. Thanks!
The function chain_decomposition is not what you think it is. From the docs:
The chain decomposition of a graph with respect a depth-first search tree is a set of cycles or paths derived from the set of fundamental cycles of the tree [...]
What you are probably looking for is the function number_connected_components.
See this link for details. This assumes that each connected component is a chain, i.e. that there are several disjoint subgraphs in your graph G, each corresponding to a (non-branching) polymer molecule. If that is not the case (the polymer is branched) then I you need to do something a bit more clever. For example, you could compute all shortest paths between leave nodes (atoms with a single bond).
You can find the leaf nodes by inspecting the degree of the nodes with list(G.degree) (leaves have degree 1), and then compute the shortest paths with between all leaf pairs with all_shortest_paths.
To find cyclic molecules you can use chain_decomposition as before.

Broadcasting a graph in Pregel Api in Graphx?

What I would like to do is to broadcast the graph I created to all of the vertices and then each vertex can do its own computation on this graph to compute shortest path with respect to itself as the source vertex? The code below always when I try accessing the graph in the method compute gives me:
java.lang.NullPointerException
val result=graph.pregel(graph,Int.MaxValue,EdgeDirection.Out)((id, value, msg) => compute(msg,id),triplet => Iterator.empty,(a, b) => a)
Unless you have iterative limitations, or want to compute the shortest path to a (temporally) changing node, it might be far easier to compute this with the help of org.apache.spark.graphx.lib.ShortestPaths [1], and calling this on each of your vertices.
Either way, the memory consumption for this will blow out of proportion for only medium-sized graph. Unless you have a really large cluster, or only a small graph, this will most likely be an insurmountable task.
Providing further information on your setting could maybe improve the answers given.
Here is answer to this question if someone out there is trying to do the same thing.
First, as GraphX uses RDDs to store the graph vertices and edges it won't be possible to broadcast a graph this way because we cannot access an RDD inside another RDD.
This is why you are getting a java.lang.NullPointerException.
Second, broadcasting the graph like that is a bad idea, you should probably think of distributed way to compute the shortest paths for each vertex. For example, instead of having one source vertex, you can trigger the shortest path computation from every single vertex and label your messages with both length and source to distinguish between different paths.

Resources