Finding a path from node A to node B in a digraph - algorithm

I'm trying to implement an algorithm to find a path between two nodes in a digraph which can have cycles.
I have readed a lot but I can't find anything that fits my requirements exactly (Dijkstra, Bellman–Ford, DFS, ...)
In my case, I have a function which gives me the following node (it can have different implementations) so, in the first version of my algorithm I just used that function to traverse the graph.
The problem, I can get blocked in a loop.
Solution 1: store nodes used and do not follow edges to that node.
This is not a good solution for me because I want to get into loops but not for infinite.
Solution 2: store edges used and do not use them twice. I can get into a loop but I can go out from an unused edge. But I still can get blocked if I have used all the edges which go out from a node and I reach that node again. I tried not to take into account used edges in this blocking situation but it's not a good solution because I can get into a llop for infinite (I think / not probed)
Now, I'm at the starting point and I want a good solution for my problem but I can't find it after some investigations.
My idea is to implement a DFS algorithm using a custom function to get the following node but I need to deal with the loop problem somehow.

Related

How to make a start on a graph traversal algorithm (where edges are one way only)

My assignment asks:
In a game, a set of nodes is connected via some set of one-way edges.
At every node there is an object to pick up. Design an algorithm to find a path that you can follow to collect all objects, if this is possible. To make your task easier, you know that starting from any node, no matter what path you follow, you will never get back to the same node.
My idea here is if I start a node at the beginning, then simply I can follow the path to collect all the nodes. However, I'm stuck on which method should I used to find the starting point. Since the question mentions all the edges are one-way which means this is direct graph. If I starting from a node in the middle, how is that possible to go through all the nodes without going back to the same node.
In addition, could someone explain what exactly one-way edges means, because I'm not sure I understand correctly on this question.
As it is an assignment, here is a hint only - as the graph is acyclic, then the only case where you would be able to visit every node is if there is a path through each node in order.
a--->b--->c
\ /
\->d--/
There is no path than goes through all of a,b,c and d.
a--->b----->c
\ \ /
\--->d--/
there is an order a,b,d,c which goes through all nodes.
So you need to look for a means to order nodes in an acyclic graph in a before/after relationship.

Find min cost from node A to node B and also keep the path info

I got a question which is to find the min cost from the least number node (1) to the largest number node (7).
The cost is the edge between nodes. I labeled them.
This problem got me to think of the Dijkstra which leads the time complexity for O((v+e) log v)
Any other better approach to solving this question efficiently?
The other requirement is to keep the path information, any thought to keep the path?
As others pointed out, the complexity is as you say and cannot be better. As #nico-schertler commented, searching from both sides in parallel (or taking turns) and stopping as soon as something touches is faster than doing just a search from one side, but it will have the same complexity. It is possible in this case (with fixed costs for the bidirectional edges) but it needs not be in the general case (e. g. cost depending on the already taken path) where Dijkstra is still applicable.
Concerning the keeping of the path: Of course, the whole thing often only makes sense if you get the path to be taken as an answer. There are two main approaches to get the path as a result.
One is to store the path already taken to a certain node along with the node in the lists (white/grey in the classical implementation). Each time you add a new node, you extend the path of its former node by one step. If you find the target node, you can directly return the path as a result (along with the cost sum). Of course this way means uses a lot of memory.
The other is to not store the origin node along with each new found node, so each node points to the node it was visited from first. Think of it as putting up signposts in each node how to go back. This way, if you find the target node, you will have to go backwards from each node to the one it was first visited from and build the path in reverse order in the process. Then you can return this path.

Finding the longest path in a directed cyclic graph

Let's say we have a directed cyclic graph where every node has an edge going to exactly two other nodes - except for a 'final node', which just has multiple things going into it and nothing coming out.
Given a source, I want to find the longest possible path to that final node that doesn't hit a node more than once. There are algorithms out there to do this, but the only problem is that my graph has many different cycles, some of which are inside each other, and most naive algorithms get stuck in infinite loops when evaluated.
I tried collapsing all strongly connected components (of which there is only one), however if the source I want is inside that component, the algorithm doesn't work. And it doesn't work in the general case either, because within that strongly connected component, to hit every node you may have to hit some nodes multiple times, which I don't want.
What's an efficient algorithm I can use for calculating the longest path back to the final vertex in an unweighted directed, cyclic graph such that no node is hit multiple times?
You can see this question, it's also a problem about finding the longest path in a directed cyclic graph, and the standard code is also available.
Question:http://poj.org/problem?id=3592
Answer: https://blog.csdn.net/u013514182/article/details/42364173

Graph traversal using every edge

I have a state diagram where each state has a list of other states it can visit. My goal is to generate as many paths as necessary from state Open to state Closed such that every state transition is used.
I'm currently thinking of converting my state table into a graph, then using a graph traversal algorithm to generate my paths.
Problem is, I don't know if an algorithm exists to fit my exact scenario. I was looking at Eulerian paths, which hit every edge only once if possible. This is not ideal because there are multiple nodes that only have a way in and no way out.
Then, I was thinking of using Bellman Ford to generate paths to these closed nodes, and removing edges used in these paths and running it again.
Hopefully I described the problem well enough, let me know if there's something I can do. Thanks.

An algorithm to check if a vertex is reachable

Is there an algorithm that can check, in a directed graph, if a vertex, let's say V2, is reachable from a vertex V1, without traversing all the vertices?
You might find a route to that node without traversing all the edges, and if so you can give a yes answer as soon as you do. Nothing short of traversing all the edges can confirm that the node isn't reachable (unless there's some other constraint you haven't stated that could be used to eliminate the possibility earlier).
Edit: I should add that it depends on how often you need to do queries versus how large (and dense) your graph is. If you need to do a huge number of queries on a relatively small graph, it may make sense to pre-process the data in the graph to produce a matrix with a bit at the intersection of any V1 and V2 to indicate whether there's a connection from V1 to V2. This doesn't avoid traversing the graph, but it can avoid traversing the graph at the time of the query. I.e., it's basically a greedy algorithm that assumes you're going to eventually use enough of the combinations that it's easiest to just traverse them all and store the result. Depending on the size of the graph, the pre-processing step may be slow, but once it's done executing a query becomes quite fast (constant time, and usually a pretty small constant at that).
Depth first search or breadth first search. Stop when you find one. But there's no way to tell there's none without going through every one, no. You can improve the performance sometimes with some heuristics, like if you have additional information about the graph. For example, if the graph represents a coordinate space like a real map, and most of the time you know that there's going to be a mostly direct path, then you can attempt to have the depth-first search look along lines that "aim towards the target". However, imagine the case where the start and end points are right next to each other, but with no vector inbetween, and to find it, you have to go way out of the way. You have to check every case in order to be exhaustive.
I doubt it has a name, but a breadth-first search might go like this:
Add V1 to a queue of nodes to be visited
While there are nodes in the queue:
If the node is V2, return true
Mark the node as visited
For every node at the end of an outgoing edge which is not yet visited:
Add this node to the queue
End for
End while
Return false
Create an adjacency matrix when the graph is created. At the same time you do this, create matrices consisting of the powers of the adjacency matrix up to the number of nodes in the graph. To find if there is a path from node u to node v, check the matrices (starting from M^1 and going to M^n) and examine the value at (u, v) in each matrix. If, for any of the matrices checked, that value is greater than zero, you can stop the check because there is indeed a connection. (This gives you even more information as well: the power tells you the number of steps between nodes, and the value tells you how many paths there are between nodes for that step number.)
(Note that if you know the number of steps in the longest path in your graph, for whatever reason, you only need to create a number of matrices up to that power. As well, if you want to save memory, you could just store the base adjacency matrix and create the others as you go along, but for large matrices that may take a fair amount of time if you aren't using an efficient method of doing the multiplications, whether from a library or written on your own.)
It would probably be easiest to just do a depth- or breadth-first search, though, as others have suggested, not only because they're comparatively easy to implement but also because you can generate the path between nodes as you go along. (Technically you'd be generating multiple paths and discarding loops/dead-end ones along the way, but whatever.)
In principle, you can't determine that a path exists without traversing some part of the graph, because the failure case (a path does not exist) cannot be determined without traversing the entire graph.
You MAY be able to improve your performance by searching backwards (search from destination to starting point), or by alternating between forward and backward search steps.
Any good AI textbook will talk at length about search techniques. Elaine Rich's book was good in this area. Amazon is your FRIEND.
You mentioned here that the graph represents a road network. If the graph is planar, you could use Thorup's Algorithm which creates an O(nlogn) space data structure that takes O(nlogn) time to build and answers queries in O(1) time.
Another approach to this problem would allow you to ignore all of the vertices. If you were to only look at the edges, you can produce a transitive closure array that will show you each vertex that is reachable from any other vertex.
Start with your list of edges:
Va -> Vc
Va -> Vd
....
Create an array with start location as the rows and end location as the columns. Fill the arrays with 0. For each edge in the list of edges, place a one in the start,end coordinate of the edge.
Now you iterate a few times until either V1,V2 is 1 or there are no changes.
For each row:
NextRowN = RowN
For each column that is true for RowN
Use boolean OR to OR in the results of that row of that number with the current NextRowN.
Set RowN to NextRowN
If you run this algorithm until the end, you will quickly have a complete list of all reachable vertices without looking at any of them. The runtime is proportional to the number of edges. This would work well with a reasonable implementation and a reasonable number of edges.
A slightly more complex version of this algorithm would be to only calculate the vertices reachable by V1. To do this, you would focus your scope on the ones that are currently reachable at any given time. You can also limit adding rows to only one time, since the other rows are never changing.
In order to be sure, you either have to find a path, or traverse all vertices that are reachable from V1 once.
I would recommend an implementation of depth first or breadth first search that stops when it encounters a vertex that it has already seen. The vertex will be processed on the first occurrence only. You need to make sure that the search starts at V1 and stops when it runs out of vertices or encounters V2.

Resources