There is a custom implementation of KSPA which needs to be re-written. The current implementation uses a modified Dijkstra's algorithm whose pseudocode is roughly explained below. It is commonly known as KSPA using edge-deletion strategy i think so. (i am a novice in graph-theory).
Step:-1. Calculate the shortest path between any given pair of nodes using the Dijkstra algorithm. k = 0 here.
Step:-2. Set k = 1
Step:-3. Extract all the edges from all the ‘k-1’ shortest path trees. Add the same to a linked list Edge_List.
Step:-4. Create a combination of ‘k’ edges from Edge_List to be deleted at once such that each edge belongs to a different SPT (Shortest Path Tree). This can be done by inspecting the ‘k’ value for each edge of the combination considered. The ‘k’ value has to be different for each of the edge of the chosen combination.
Step:-5. Delete the combination of edges chosen in the above step temporarily from the graph in memory.
Step:-6. Re-run Dijkstra for the same pair of nodes as in Step:-1.
Step:-7. Add the resulting path into a temporary list of paths. Paths_List.
Step:-8. Restore the deleted edges back into the graph.
Step:-9. Go to Step:-4 to get another combination of edges for deletion until all unique combinations are exhausted. This is nothing but choosing ‘r’ edges at a time among ‘n’ edges => nCr.
Step:-10. The ‘k+1’ th shortest path is = Minimum(Paths_List).
Step:-11. k = k + 1 Go to Step:-3, until k < N.
Step:-12. STOP
As i understand the algorithm, to get kth shortest path, ‘k-1’ SPTs are to be found between each source-destination pair and ‘k-1’ edges each from one SPT are to be deleted simultaneously for every combination.
Clearly this algorithm has combinatorial complexity and clogs the server on large graphs. People suggested me Eppstein's algorithm (http://www.ics.uci.edu/~eppstein/pubs/Epp-SJC-98.pdf). But this white paper cites a 'digraph' and I did not see a mention that it works only for digraphs. I just wanted to ask folks here if anyone has used this algorithm on an undirected graph?
If not, are there good algorithms (in terms of time-complexity) to implement KSPA on an undirected graph?
Thanks in advance,
Time complexity: O(K*(E*log(K)+V*log(V)))
Memory complexity of O(K*V) (+O(E) for storing the input).
We perform a modified Djikstra as follows:
For each node, instead of keeping the best currently-known cost of route from start-node. We keep the best K routes from start node
When updating a nodes' neighbours, we don't check if it improves the best currently known path (like Djikstra does), we check if it improves the worst of the K' best currently known path.
After we already processed the first of a nodes' K best routes, we don't need to find K best routes, but only have K-1 remaining, and after another one K-2. That's what I called K'.
For each node we will keep two priority queues for the K' best currently known path-lengths.
In one priority queue the shortest path is on top. We use this priority queue to determine which of the K' is best and will be used in the regular Djikstra's priority queues as the node's representative.
In the other priority queue the longest path is on top. We use this one to compare candidate paths to the worst of the K' paths.
Related
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.
I have questions about an optimal algorithm problem on a weighted graph. I am given an edgelist with weights, a list with savepoints, a starte- and end- node and the max distance for a step.
The output should be a list of savepoints, which are accessible in one step from starting- and end- node.
I thought of some kind of dijkstra's algorithm from each point of the list of savepoints.
I'm not sure if that's a good idea, since if I have many savepoints I calculate a lot of paths multiple times. Every idea/help is welcome!
Thank you very much in advance!
You have to have the condition that a weight cannot be negative, otherwise the problem becomes very intractable. Otherwise it's just a breadth first search, with marking the distance for every visited node. So you don't revisit a node is a previous move has visited it earlier at lower cost.
You keep a priority queue of all active nodes, so you are checking the lowest cost node each time. The priority queue is in fact the hardest part to get right. If you check the A* algorithm for my binary image library https://github.com/MalcolmMcLean/binaryimagelibrary you can take the priority queue for there. A* over a maze is very similar to shortest path over a graph, but you don't have a heuristic because you must have the exact shortest path, and instead of 4 / 8 edges per tile, you have nodes with arbitrary numbers of connections.
I have a weighted graph G and a pair of nodes s and t. I want to find, of all the paths from s to t with the fewest number of edges, the one that has the lowest total cost. I'm not sure how to do this. Here are my thoughts:
I am thinking of finding the shortest path and if there are more than one path then i should compare the number of steps of these paths.
I think I can find the number of steps by setting the weights of all edges to 1 and calculate the distance.
A reasonable first guess for a place to start here is Dijkstra's algorithm, which can solve each individual piece of this problem (minimize number of edges, or minimize total length). The challenge is getting it to do both at the same time.
Normally, when talking about shortest paths, we think of paths as having a single cost. However, you could imagine assigning paths two different costs: one cost based purely on the number of edges, and one cost based purely on the weights of those edges. You could then represent the cost of a path as a pair (length, weight), where length is the number of edges in the path and weight is the total weight of all of those edges.
Imagine running Dijkstra's algorithm on a graph with the following modifications. First, instead of tracking a candidate distance to each node in the graph, you track a pair of candidate distances to each node: a candidate length and a candidate weight. Second, whenever you need to fetch the lowest-code node, pick the node that has the shortest length (not weight). If there's a tie between multiple nodes with the same length, break the tie by choosing the one with the lowest weight. (If you've heard about lexicographical orderings, you could consider this as taking the node whose (length, weight) is lexicographically first). Finally, whenever you update a distance by extending a path by one edge, update both the candidate length and the candidate weight to that node. You can show that this process will compute the best path to each node, where "best" means "of all the paths with the minimum number of edges, the one with the lowest cost."
You could alternatively implement the above technique by modifying all the costs of the edges in the graph. Suppose that the maximum-cost edge in the graph has cost U. Then do the following: Add U+1 to all the costs in the graph, then run Dijkstra's algorithm on the result. The net effect of this is that the shortest path in this new graph will be the one that minimizes the number of edges used. Why? Well, every edge adds U+1 to the cost of the path, and U+1 is greater than the cost of any edge in the graph, so if one path is cheaper than another, it either uses at least one fewer edge, or it uses the same number of edges but has cheaper weights. In fact, you can prove that this approach is essentially identical to the one above using pairs of weights - it's a good exercise!
Overall, both of these approaches will run in the same time as a normal Dijkstra's algorithm (O(m + n log n) with a Fibonacci heap, O(m log n) with another type of heap), which is pretty cool!
One node to another would be a shortest-path-algorithm (e.g. Dijkstra).
It depends on your input whether you use a heuristic function to determine the total distance to the goal-node.
If you consider heuristics, you might want to choose A*-search instead. Here you just have to accumulate the weights to each node and add the heuristic value according to it.
If you want to get all paths from any node to any other node, you might consider Kruskal’s or Prim’s algorithm.
Both to basically the same, incl. pruning.
I have a follow-up question on this:
Finding shortest path distances in a graph containing at most two negative edges
Ranveer's solution looks great, but it is not fast enough because I need O(|E| + |V|*log|V|) fast algorithm.
I guess Dukeling's solution works great. It makes sense and it operates in the same running time of Dijkstra's algorithm.
However, my goal is to find shortest path distances from a given node s to ALL the nodes in V.
If I apply Dukeling's algorithm by setting all the nodes in V as end vertex e, I will need to run it |V| - 1 times. Then, the running time will be O(|V||E| + |V^2|*log|V|).
Any help would be appreciated!
Dijkstra's algorithm, in its original form, finds all the shortest paths from a source node to all other nodes in the graph.
You have (at least) two options for your problem:
Use Bellman - Ford. It's not as slow as its big-oh would suggest, at least not necessarily. Make sure you implement it like you would a BF search: using a FIFO queue. This means you will insert a node into the queue every time the distance to it is updated, and only if it isn't already in the queue. Other optimizations are also possible, but this should already give you a fast algorithm in practice;
Use Dijkstra's, but modified similarly to Bellman - Ford: the default Dijkstra's never inserts a node twice into the priority queue. Make sure you reinsert nodes if you have updated the distance to them. This will deal with negative cost edges. It essentially makes the algorithm closer to the Bellman - Ford described above, but using a priority queue instead of a FIFO queue. This will also get you closer to your desired complexity.
Latest news about underground bombing made me curious about the following problem. Assume we have a weighted undirected graph, nodes of which are sometimes removed. The problem is to re-calculate shortest paths between all pairs of nodes fast after such removals.
With a simple modification of Floyd-Warshall algorithm we can calculate shortest paths between all pairs. These paths may be stored in a table, where shortest[i][j] contains the index of the next node on the shortest path between i and j (or NULL value if there's no path). The algorithm requires O(n³) time to build the table, and eacho query shortest(i,j) takes O(1). Unfortunately, we should re-run this algorithm after each removal.
The other alternative is to run graph search on each query. This way each removal takes zero time to update an auxiliary structure (because there's none), but each query takes O(E) time.
What algorithm can be used to "balance" the query and update time for all-pairs shortest-paths problem when nodes of the graph are being removed?
As mentioned by goran, you only have to recalculate those shortest paths which contained a node that was removed in the meanwhile. So, I'd do the following:
Calculate all the shortest paths using the Floyd-Warshall algorithm. This is O(n3).
Create an index which assigns vertex indices to the list of shortest paths that vertex participates in. (In other words, for every vertex i, it gives you a list of (j, k) pairs s.t. i is present in the shortest path between vertex j and k). This is O(n2d) (where d is the graph diameter) since you have to loop over each vertex in each of the shortest path determined in the previous step, and there are n2 such shortest paths.
After a vertex removal, look up the list of the affected shortest paths from the index created in step 2 and recalculate them. Since you don't need all the shortest paths here and I assume that only a few nodes are affected, you are probably better off with multiple breadth first searches, which is O(m + n) where m is the number of edges.
I'll answer the implied non-generic variant of the problem, where the graph is a road network. This seems to me one of the cases where theoretical bounds on arbitrary graphs are less interesting.
Some of the best approaches for shortest path finding are highway-node routing and transit-node routing. (described in a dissertation by Dominik Schultes). The acceleration structure can be built reasonably fast (~15 min. for the HNR of the whole Europe) and it supports incremental updates. What's interesting is that query times for random queries is around 1ms, and all-pairs distance tables can be calculated for as low as 0.2us per entry. What's even more interesting is the query performance scaling, data suggests that the scaling is sub-logarithmic/near-constant in graph size. Transit node routing is even faster at 4.3us random queries. Alas I don't have any information on the updatability of the datastructure. Intuitively it shouldn't be too hard to incrementally update.
The same or similar approaches could be used on other graphs that are similar to road networks (sparse, planar, hierarchical).
Well I don't think that you need to rerun the whole build if a node is removed. Only for those paths which had a node in them.
Trivial solution to your problem would be to add information about redundant paths, for example you could have a second shortest path for each of the nodes on the shortest path.
This does not reduce the computation time, but caches it (it also increase storage requirements by a factor of n, where n is average number of nodes, for a single node removal, by factor of n*(n-1) for 2 node redundancy... and by factor of n! for complete redundancy and also increases initial build time by the same factor and also increases the time needed to add nodes)
If there is a way to improve this and reduce the rebuild time then you need to find a structure that would allow a quick computation of the shortest distance but that should be immutable (or cheap to recalculate) when nodes are removed or added to a graph.
Quick concept of Floyd-Warshall Algorithm!
The first loop in the algorithm is a new node which is introduced in addition to the existing nodes. We will run the algorithm to relax all the existing node distances with the new introduced node.
In this problem we will reverse the order of removal of the nodes and hence the removed nodes will act as an adding node.
-- given the deleted array del[n];
-- we will traverse from the end of deleted array.
for(int k=n; k>=1; k--)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
graph[i][j] = min(graph[i][j],graph[i][del[k]] + graph[del[k]][j]);
-- Now traverse through the all k to n nodes and find the required all pair distances in each iteration and store it in a vector.
-- finally, reverse the vector to get the required all pair distances.
So running time of the algorithm is as the same as Floyd Warshall algorithm, i.e. O(n3).