Finding the longest path in a complete directed graph - algorithm

I was thinking on how to find a longest possible path in a complete, directed graph for every single vertex.
Example of such a graph
So for every single vertex I want to find the maximum possible amount of vertices that one can travel through (not going through any vertex more than once) and the specific path that has that specific length.
For example in the given graph, for starting vertex nr.1, the maximum length is 4 and the path:
1,4,2,3 ,or 1,2,3,4 (I just need to get one of them, not all).
What kind of algoritm could handle that?
In case it matters I use C++.

Related

Constructing an Algorithm which takes as Input Two DAG's and Returns the Longest Path found in Both

Construct and describe an efficient algorithm which takes as input two directed acyclic graphs (DAG's) and finds the longest path which occurs in both of them.
If there are several, the algorithm should return one of the longest paths (it doesn't matter which one). In summary, given the graphs G = (V,E) and G' =(V',E'), find the longest possible sequence <v1,...,vk> where (v_i,v_{i+1}) is in E and E' for i = 1...k-1.
Any ideas? I can write the actual code myself, I just need help with building the idea behind the actual algorithm and finding a solution to the problem.
Im thinking I could use recursive DFS and some memoization: while keeping track of visited nodes; for each starting node and for each neighbour, calculating the distance to the neighbour + the distance from the neighbour to the goal. Then taking the max of these, memoizing it as the max from this node, and returning it.
Using this approach for both DAG's, the issue from here would be to identify which of these paths is the longest that occurs in both.
Would appreciate any ideas/help.
Two approaches:
Starting from every vertex, figure out what is the longest common path. DFS+memoize. Return the max length. If you want the path as well, memoize the longest path as well.
Find the intersection of the DAGs and return the longest intersecting path. You can find here code for intersection of graphs. Similarly, you can do for DAGs as well.
In approach 1, you don't need to store the intersecting parts of the DAG, just the max length is sufficient. So, it is memory efficient as compared to approach two.
In first approach, you find out length of maximum matching path (BCD here) and return the length.
In second approach, you'll store the matching parts (BCD here) and return the longest path length from it.
Approach 3:
#"n. 1.8e9-where's-my-share m." mentions another approach in the comments where you delete the edges from one graph which are not present in another graph.
So, if you delete from graph 1 the edges which are not present in graph 2, you'll get the below:
In the above graph if you do the DFS, you'll get 3 as answer as BCD is the longest path.

Storing Augmenting Path For Maximum Graph Matching

I am trying to write a maximum graph matching algorithm for my thesis. I stuck on how to store the augmenting path on the augmentation step of the algorithm. First, I will write the actual problem I am trying to solve. Then I will try to simplify it.
Suppose you have a graph, where a node can be matched with one of its neighbours and you are trying to calculate the maximum matching. Each node is connected to exactly three other nodes. You did your best, but some nodes left unmatched so you need to do augmentation. At this point, you already know the matchings and the list of nodes that remain unmatched. Augmentation process works like this: You pick two nodes from the unmatched nodes list and find an alternating path between them. An alternating path consists of the two nodes mentioned and a list of matched nodes in between. It is called an alternating path because matched and unmatched edges between nodes alternate along the path.
You can find an alternating path between any two unmatched nodes, but picking the closer ones are better for the performance of the algorithm. So instead, you pick an unmatched node and do BFS until you reach another unmatched node. When you find one such path (which satisfies the alternating path rule), you swap the matchings so the unmatched nodes are now matched.
In short, I need to run some sort of BFS algorithm where there are two types of edges (let's say red and black) and these edges shall alternate along the path until I reach my destination. In the end, I need the path from my source to the closest of the possible destinations which satisfy the red/black rule.
I was able to come up with the pseudocode of the algorithm but I don't know how to store the alternating path that the algorithm finds. How can do it? Any alternative strategies are also welcome.

Algorithm: Minimal path alternating colors

Let G be a directed weighted graph with nodes colored black or white, and all weights non-negative. No other information is specified--no start or terminal vertex.
I need to find a path (not necessarily simple) of minimal weight which alternates colors at least n times. My first thought is to run Kosaraju's algorithm to get the component graph, then find a minimal path between the components. Then you could select nodes with in-degree equal to zero since those will have at least as many color alternations as paths which start at components with in-degree positive. However, that also means that you may have an unnecessarily long path.
I've thought about maybe trying to modify the graph somehow, by perhaps making copies of the graph that black-to-white edges or white-to-black edges point into, or copying or deleting edges, but nothing that I'm brain-storming seems to work.
The comments mention using Dijkstra's algorithm, and in fact there is a way to make this work. If we create an new "root" vertex in the graph, and connect every other vertex to it with a directed edge, we can run a modified Dijkstra's algorithm from the root outwards, terminating when a given path's inversions exceeds n. It is important to note that we must allow revisiting each vertex in the implementation, so the key of each vertex in our priority queue will not be merely node_id, but a tuple (node_id, inversion_count), representing that vertex on its ith visit. In doing so, we implicitly make n copies of each vertex, one per potential visit. Visually, we are effectively making n copies of our graph, and translating the edges between each (black_vertex, white_vertex) pair to connect between the i and i+1th inversion graphs. We run the algorithm until we reach a path with n inversions. Alternatively, we can connect each vertex on the nth inversion graph to a "sink" vertex, and run any conventional path finding algorithm on this graph, unmodified. This will run in O(n(E + Vlog(nV))) time. You could optimize this quite heavily, and also consider using A* instead, with the smallest_inversion_weight * (n - inversion_count) as a heuristic.
Furthermore, another idea hit me regarding using knowledge of the inversion requirement to speedup the search, but I was unable to find a way to implement it without exceeding O(V^2) time. The idea is that you can use an addition-chain (like binary exponentiation) to decompose the shortest n-inversion path into two smaller paths, and rinse and repeat in a divide and conquer fashion. The issue is you would need to construct tables for the shortest i-inversion path from any two vertices, which would be O(V^2) entries per i, and O(V^2logn) overall. To construct each table, for every entry in the preceding table you'd need to append V other paths, so it'd be O(V^3logn) time overall. Maybe someone else will see a way to merge these two ideas into a O((logn)(E + Vlog(Vlogn))) time algorithm or something.

Which algorithm returns the shortest sequence to exchange information between knots of a graph?

Is there a Tool or known algorithmic method, which could compute the shortest sequence to transmit an information between the knots of a graph - e.g. graph threeC ?
Example: threeC
Time 0: A=a; B=b; C=c; D=d
Time 1: A=abcd; B=b; C=c; D=d
Time 2: A=abcd; B=bacd; C=cabd; D=dabc
I've looked into petri-nets, it would have to be a coloured net with directed and multiple edges - I guess. However I am quite uncertain, if I am on the right track.
It would have to work for connected unlabelled Graphs up to 5 knots (there are 21 of those). I would like to know - better proof - the shortest way of distributing abcd amongst all 5 knots (for all of those 21 graphs).
So, is there an algorithm or field of research that fits to this problem?
Thank you for your help.
If I understand correctly the question is actually to find the shortest path to the vertex that is father from starting vertex. That would be exactly what Dijkstra would do very well. You basically only assign a start node for Dijkstra and let it run until it has visited all nodes.
Dijkstra would leave behind information required for output.
If output is single value telling the maximum shortest path you can simple keep track of distance and print the highest distance when algorithm terminates. If requirement is to output also paths then Dijkstra would need to store information which edges it used to travel from a vertices that resulted to the shortest path in other end of vertex (there could be multiple equal entrances to a vertex requiring all sources to have their edges marked as used for route if all paths are required for output.)
http://en.wikipedia.org/wiki/Dijkstra's_algorithm

Random walk for find the path with higher cost

I have a acyclic directed graph with a start vertice and an end vertice and some unknown number of vertices in between. A path starts from start vertice and end at end vertice. It is known that the number of vertices along the any paths between the start vertice and end vertice <100, but the number of possible vertices could be very large. Each vertice has a cost assigned to it, and the cost of the path is summation of the cost of vertices in between. Is there a way to use the random walk or any other means (this is to avoid explore all the vertices) to find for the path that has the highest (or near-highest) cost?
This problem is solved on Geekviewpoint.com with detailed explanation. It augments Dijkstra's algorithm. http://www.geekviewpoint.com/java/graph/dijkstra_constrained
EDIT: to account for 100 vertices between each path.
Originally your problem said there were 100 paths between the start and finish vertices. But by your correction, it's actually 100 vertices on the path. In that case your optimization is straightforward using DFS.
As you try to assemble a path, track the number of vertices you have seen. If the number reaches 99 and does not link start to finish, abort that path and try another one unit you get the answer if it exists. The algorithm you need to modify is DFS for cycle detection. Any algorithm textbook will have one of those. Since you also need to pick the best path among those found, you should also look at http://www.geekviewpoint.com/java/graph/count_paths.
I don't know if I should tell you how to do the obvious, but you will track the past path you have found similar to how you would find the maximum element in an array. The code is not difficult, you just have to combine a few small ideas:
DFS (similar to cycle detection and similar to counting paths, the two overlap)
track the best path you have seen: a one entry map where the idea is map which you keep replacing if you find a shorter path.

Resources