I was wondering if you are aware of an algorithm to enumerate all possible simple paths in a graph from a single source, without repeating any of the vertices. keep in mind that the graph will be very small (16 nodes) and relatively sparse (2-5 edges per node).
To make my question clear:
Vertices: A,B,C
A connects to B, C
B connects to A, C
C connects to A, B
Paths (from A):
A,B
A,C
A,B,C
A,C,B
Vertices: A,B,C,D
A connects to B, C
B connects to A, C, D
C connects to A, B, D
Paths (from A):
A,B
A,C
A,B,C
A,B,D
A,C,B
A,C,D
A,B,C,D
A,C,B,D
It is surely not BFS or DFS, although one of their possible variants might work. Most of the similar problems I saw in SO, were dealing with pair of nodes graphs, so my problem is slightly different.
Also this Find all possible paths from one vertex in a directed cyclic graph in Erlang is related, but the answers are too Erlang related or it is not clear what exactly needs to be done. As I see, the algorithm could be alternatively be decribed as find all possible simple paths for a destined number of hops from a single source. Then for number of hops (1 to N) we could find all solutions.
I work with Java but even a pseudocode is more than enough help for me.
In Python style, it is a BFS with a different tracking for visited:
MultiplePath(path, from):
from.visited = True
path.append(from)
print(path)
for vertex in neighbors(from):
if (not vertex.visited):
MultiplePath(path, vertex)
from.visited = False
Return
Related
I have a large network table that I want to simplify by merging nodes that share the same interactions, so that it will have a better network once imaged (I am using Cytoscape). The interactions do not have direction. As a mini example, if I have a table such as below.
A E
B E
C G
C H
D G
H D
E F
R S
The two columns are nodes that interact with each other. In this case since nodes A, B and F all only have connections to node E, I want to merge them so it's A,B,F as one node that interacts with E. Similarly since both C and D only interact with G and H I would want to merge them together. The resulting table should look something like below.
A,B,F E
C,D G
C,D H
R S
I have created a list with all the nodes, but I am not sure how to see if they have matching interactions since they can be in either column. Is there a good way/program to handle this?
For most networks, there would not be single solution to this problem. Once you start collapsing you begin to exclude other equally valid solutions. For example, even in your simplified example, these are other valid solutions:
A,B,F E
G,H C
G,H D
R S
or even
A,B,F E
C,D G,H
R S
And it gets more complicated once you include interactions across your relatively clean example, e.g., A G. But if your data really is partitioned like this example (which should be immediately apparent when you load it into iGraph or Cytoscape and perform any basic layout to see a bunch of separate networks), then you might be able to get a solution by querying all interaction partners for each node, then collapsing based on identical partner sets.
I don't know of a function iGraph or Cytoscape that can do this for you.
And if you network is not a partitioned set of multiple networks, then I don't think this is feasible at all.
Do I understand it right, that your cytoscape graph contains all said elements and the 'interactions' stand for edges in cytoscape? Because if your network has said elements and edges, you could, for example (this will not be a fast solution I think), make an array with all id' of your elements with
cy.nodes();
and then call
Object.keys(cy.edges("[target = '" + nodeId + "']")).length;
on every node in the array and save the number of edges going out of said node in the array. This way you can find all nodes with at least x nodes attached and then you can do whatever you want. You could e.g make the selected nodes to parents, so that the connected nodes are now inside the parent nodes?
Please tell me if this helps you or not :)
I have a typical friend of friend graph database i.e. a social network database. The requirement is to extract all the nodes as a list in such a way that the least connected nodes appear together in the list and the most connected nodes are placed further apart in the list.
Basically its asking a graph to be represented as a list and I'm not sure if we can really do that. For e.g. if A is related to B with strength 10, B is related to C with strength 80, A to C is 20
then how to place this in a list ?
A, B, C - no because then A is distant from C relatively more than B which is not the case
A, C, B - yes because A and B are less related that A,C and C,B.
With 3 nodes its very simple but with lot of nodes - is it possible to put them in a list based on relationship strength ?
Ok, I think this is maybe what you want. An inverse of the shortestPath traversal with weights. If not, tell me how the output should be.
http://console.neo4j.org/r/n8npue
MATCH p=(n)-[*]-(m) // search all paths
WHERE n <> m
AND ALL (x IN nodes(p) WHERE length([x2 IN nodes(p) WHERE x2=x])=1) // this filters simple paths
RETURN [n IN nodes(p)| n.name] AS names, // get the names out
reduce(acc=0, r IN relationships(p)| acc + r.Strength) AS totalStrength // calculate total strength produced by following this path
ORDER BY length(p) DESC , totalStrength ASC // get the max length (hopefully a full traversal), and the minimum strength
LIMIT 1
This is not going to be efficient for a large graph, but I think it's definitely doable--probably needs using the traversal/graphalgo API shortest path functionality if you need speed on a large graph.
In a graph I need to find a shortest path between two points and on the way visit one checkpoint. Also, I can visit each vertex only once. I suppose it have something to do with network flow but I have no idea how to implement that.
You can model it entirely as a capacitated multicommodity minimum cost flow problem. You want to go from A to B via C without using a vertex twice. You can model it as a flow from A to C (commodity 1) and a flow from B to C (commodity 2). To avoid a node being used twice, you have to perform the following trick on all your nodes (in your model):
Given a node X with p incoming and t outgoing edges, you create a new node Y and rewire the links. The p incoming links will all arrive in X, the q outgoing edges will all depart from Y. Add only 1 link (L) from X to Y. By setting the capacity of the L-link to 1, each node will only be used once.
You can then write it down as an (M)ILP and have it solved. The ILP will give you the correct solution if it exists. Depending on your application, it might be overkill. If you want a fast heuristic, just use 2 A* searches and hope they don't overlap.
I was wondering, that if there is a weighted graph G(V,E), and I need to find a single shortest path between any two vertices S and T in it then I could have used the Dijkstras algorithm. but I am not sure how this can be done when we need to find all the distinct shortest paths from S to T. Is it solvable on O(n) time? I had one more question like if we assume that the weights of the edges in the graph can assume values only in certain range lets say 1 <=w(e)<=2 will this effect the time complexity?
You can do it using Dijkstra. In Dijkstra's algorithm, you assign labels to each node based on the distance it has from your source and settle nodes according to this distance (smallest first). Once the target node is settled, you have the length of the shortest path. To retrieve the path (=the sequence of edges), you can keep track of the parent of each node you settle. To retrieve all possible paths, you have to account for multiple parents of each node.
A small example:
Suppose you have a graph which looks like this (all edges weight 1 for simplicity):
B
/ \
A C - D
\ /
E
When you do dijkstra to find the distance A->D, you would get 3. You would first settle node A with distance 0, then nodes B and E with distance 1, node C with distance 2 and finally node D with distance 3. To get the paths, you would remember the parents of the nodes when you settle them. In this case you would first set the parents of B and C =node A. You then need to set the parents of node C to B and E as they both supply the same length. Node D would get node C as a parent.
When you need the paths, you could just follow the parent pointers, starting at D and branching each time a node has multiple parents. This would give you a branch at node C.
The post mentioned in the comment above uses the same principles, although it does not allow you to actually extract the paths, it only gives you the count.
One final remark: Dijkstra is not a linear time algorithm as you need to do a lot of operations to maintain you queue and node sets.
(a) Using BFS from s to mark nodes visited as usual, in the meantime, changing following things:
(b) for each node v, it has a record L(v) representing the layer that v is on and a record f(v)
representing the number of incoming paths:
(c) everytime a node v1 is found in another node's v2 neighbors:
(d) if v1 is not in the queue, add it into queue, L(v1) = L(v2) + 1,f(v1)+ = f(v2)
(d) if v1 is already in the queue and L(v1) equals L(v2), do nothing.
(e) if v1 is already in the queue but L(v1) doe not equal to L(v2), f(v1)+ = f(v2)
(f) until in this modied BFS, t pop from the queue for the rst time, we have f(t)
(g) and this f(t) represents the number of dierent shortest paths from s to t
This might solve your problem.
Given an undirected cyclic graph, I want to find all possible traversals with Breadth-First search or Depth-First search. That is given a graph as an adjacency-list:
A-BC
B-A
C-ADE
D-C
E-C
So all BFS paths from root A would be:
{ABCDE,ABCED,ACBDE,ACBED}
and for DFS:
{ABCDE,ABCED,ACDEB,ACEDB}
How would I generate those traversals algorithmically in a meaningful way? I suppose one could generate all permutations of letters and check their validity, but that seems like last-resort to me.
Any help would be appreciated.
Apart from the obvious way where you actually perform all possible DFS and BFS traversals you could try this approach:
Step 1.
In a dfs traversal starting from the root A transform the adjacency list of the currently visited node like so: First remove the parent of the node from the list. Second generate all permutations of the remaining nodes in the adj list.
So if you are at node C having come from node A you will do:
C -> ADE transform into C -> DE transform into C -> [DE, ED]
Step 2.
After step 1 you have the following transformed adj list:
A -> [CB, BC]
B -> []
C -> [DE, ED]
D -> []
E -> []
Now you launch a processing starting from (A,0), where the first item in the pair is the traversal path and the second is an index. Lets assume we have two queues. A BFS queue and a DFS queue. We put this pair into both queues.
Now we repeat the following, first for one queue until it is empty and then for the other queue.
We pop the first pair off the queue. We get (A,0). The node A maps to [BC, CB]. So we generate two new paths (ACB,1) and (ABC,1). Put these new paths in the queue.
Take the first one of these off the queue to get (ACB,1). The index is 1 so we look at the second character in the path string. This is C. Node C maps to [DE, ED].
The BFS children of this path would be (ACBDE,2) and (ACBED,2) which we obtained by appending the child permutation.
The DFS children of this path would be (ACDEB,2) and (ACEDB,2) which we obtained by inserting the child permutation right after C into the path string.
We generate the new paths according to which queue we are working on, based on the above and put them in the queue. So if we are working on the BFS queue we put in (ACBDE,2) and (ACBED,2). The contents of our queue are now : (ABC,1) , (ACBDE,2), (ACBED,2).
We pop (ABC,1) off the queue. Generate (ABC,2) since B has no children. And get the queue :
(ACBDE,2), (ACBED,2), (ABC,2) and so on. At some point we will end up with a bunch of pairs where the index is not contained in the path. For example if we get (ACBED,5) we know this is a finished path.
BFS is should be quite simple: each node has a certain depth at which it will be found. In your example you find A at depth 0, B and C at depth 1 and E and D at depth 2. In each BFS path, you will have the element with depth 0 (A) as the first element, followed by any permutation of the elements at depth 1 (B and C), followed by any permutation of the elements at depth 2 (E and D), etc...
If you look at your example, your 4 BFS paths match that pattern. A is always the first element, followed by BC or CB, followed by DE or ED. You can generalize this for graphs with nodes at deeper depths.
To find that, all you need is 1 Dijkstra search which is quite cheap.
In DFS, you don't have the nice separation by depth which makes BFS straightforward. I don't immediately see an algorithm that is as efficient as the one above. You could set up a graph structure and build up your paths by traversing your graph and backtracking. There are some cases in which this would not be very efficient but it might be enough for your application.