I am trying to solve this question but got stuck.
Need some help,Thanks.
Given an undirected Connected graph G with non-negative values at edges.
Let A be a subgroup of V(G), where V(G) is the group of vertices in G.
-Find a pair of vertices (a,b) that belongs to A, such that the weight of the shortest path between them in G is minimal, in O((E+V)*log(v)))
I got the idea of using Dijkstra's algorithm in each node which will give me O(V*((E+V)logv))),which is too much.
So thought about connecting the vertices in A somehow,did'nt find any useful way.
Also tried changing the way Dijkstra's algorithm work,But it get's to hard to prove with no improvment in time complexity.
Note that if the optimal pair is (a, b), then from every node u in the optimal path, a and b are the closest two nodes in A.
I believe we should extend Dijkstra's algorithm in the following manners:
Start with all nodes in A, instead of a single source_node.
For each node, don't just remember the shortest_distance and the previous_node, but also the closest_source_node to remember which node in A gave the shortest distance.
Also, for each node, remember the second_shortest_distance, the second_closest_source_node, and previous_for_second_closest_source_node (shorter name suggestions are welcome). Make sure that second_closest_source_node is never the closest_source_node. Also, think carefully about how you update these variables, the optimal path for a node can become part of the second best path for it's neighbour.
Visit the entire graph, don't just stop at the first node whose closest_source and second_closest_source are found.
Once the entire graph is covered, search for the node whose shortest_distance + second_shortest_distance is smallest.
Related
First of all, I have to admit I'm not good at graph theory.
I have a weakly connected directed graph G=(V,E) where V is about 16 millions and E is about 180 millions.
For a given set S, which is a subset of V (size of S will be around 30), is it possible to find a weakly connected sub-graph G'=(V',E') where S is a subset of V' but try to keep the number of V' and E' as small as possible?
The graph G may change and I hope there's a way to find the sub-graph in real time. (When a process is writing into G, G will be locked, so don't worry about G get changed when your sub-graph calculation is still running.)
My current solution is find the shortest path for each pair of vertex in S and merge those paths to get the sub-graph. The result is OK but the running time is pretty expensive.
Is there a better way to solve this problem?
If you're happy with the results from your current approach, then it's certainly possible to do at least as well a lot faster:
Assign each vertex in S to a set in a disjoint set data structure: https://en.wikipedia.org/wiki/Disjoint-set_data_structure. Then:
Do a breadth-first-search of the graph, starting with S as the root set.
When you the search discovers a new vertex, remember its predecessor and assign it to the same set as its predecessor.
When you discover an edge that connects two sets, merge the sets and follow the predecessor links to add the connecting path to G'
Another way to think about doing exactly the same thing:
Sort all the edges in E according to their distance from S. You can use BFS discovery order for this
Use Kruskal's algorithm to generate a spanning tree for G, processing the edges in that order (https://en.wikipedia.org/wiki/Kruskal%27s_algorithm)
Pick a root in S, and remove any subtrees that don't contain a member of S. When you're done, every leaf will be in S.
This will not necessarily find the smallest possible subgraph, but it will minimize its maximum distance from S.
I've been trying to wrap my head around why Dijkstra's algorithm doesn't work on negative weighted graphs and I understand all examples that has a further node pointing back to a node that has been fully explored. But this examples does my head in;
Would I be correct in thinking that; first A is explored. A->B will be 1 and A->C will be 100. Then B is explored and sets B->D to 2. Then D is explored because currently it has the shortest path back to the source (i.e. At the top of the priority queue)?
Would I be correct in saying that if B->D was 100, C would've been explored first (since A->D is 101)?
The one thing that people didn't really mention in every explanation was that a node has been explored/visited, it can't be updated anymore because Dijkstra works on a priority queue. I just find it hard to wrap my head around why D is visited before C in this case.
It's straightforward: when a node using Djikstra's algorithm is explored/visited/closed this means that you have found the shortest path to that node, therefore this node does not need to be reexplored or revisited, you already know the shortest path to the node.
For instance, when you select D to be explored there are two paths in the PQ:
A-B-D with cost 2
A-C with cost 100
and the path with least cost is selected. Then, it's obvious that if arc costs are always positive there's no way that you can find a shortest path to D going through A-C. The shortest path to D has been found and the node is closed.
All this reasoning is however not true when negative arc costs are allowed, so that's why Djikstra's algorithm does not work for them.
I think Dijkstra algorithm that you are describing operates only on positive weight functions. In particular Dijkstra algorithm gives a valid metric space structure on every weighted (positively) graph. On the other hand this seems to be not the case for arbitrary weighted graphs. Take for instance the graph with two nodes A and B and one edge between them with weight -5. In this case this will not give a distance between A and B. So what you describing, I think would fall into some sort of modified Dijkstra model and the interpretation of going from one node to another can no longer be interpreted as distance between the nodes.
It is easy to prove that if P is a shortest path between u and v, then every subpath is also a shortest path.
Given a connected Graph, I want to preprocess a the shortest path between every pair of nodes in a Matrix, such that:
Path[u,v] = Path[v,u]
If x,y in Path[u,v] then Path[x,y] is a subpath of Path[u,v].
I can not figure out an algorithm or a prove and actually I do not know if this is posible.
Any idea is welcome.Thank you.
You can only get (1) if you are working with undirected graphs OR if it is guaranteed that the weight of the arc (a, b) is equal to the weight of the arc (b, a) for all arcs in your graph.
The problem you describe sounds like the all-pairs shortest path problem: for each pair of nodes in a connected graph, find the shortest paths between nodes in the pair. The Floyd-Warshall algorithm can be used to find the lengths of paths and it is straightforward to reconstruct the shortest paths from there.
This algorithm further requires that there are no negative cycles (otherwise a shorter path could always be obtained by running through that cycle again) but that requirement seems reasonable.
To guarantee property (2), you need to make sure when reconstructing paths you are reconstructing "canonical" paths whenever more than one shortest path may be possible. To do this, impose an ordering on the vertices and always test candidate nodes in ascending order, always preferring the lowest-ordered node which maintains the shortest-path property.
Wikipedia has a fairly good write-up.
In an acyclic graph, I am trying to find out whether or not a path of length L exists between two given nodes. My questions is, what is the best and the simplest Algorithm to use in this case.
Note that the graph has a maximum of 50 nodes and 100 edges.
I have tried to find all the paths using DFS and then to check if that path exists between the two nodes but I got the answer "Time Limit Exceeded" from the online judge.
I also used the Uniform Cost Search Algorithm but I also a got a negative response.
I need a more efficient way for solving such problem. Thank you.
I don't know if it will be faster then a DFS approach - but it will give a feasible solution:
Represent the graph as a matrix A, and calculate A^L - a path of length L between i and j exists if and only if A[i][j] != 0
Also, regarding DFS solution: You do not need to find all paths in the DFS - you should limit yourself to paths of length <= L, and by this trim some searches, once the length have exceeded the needed length. You could also escape the search once a path of length L is reaching the target.
Another possible optimization could be bi-directional search.
Find all vertices which have path of length L/2 from the source to
them.
Next, find all vertices which have paths of length L/2 from them
to the target (DFS on the reverse graph)
Then, check if there is a vertex that is common to both sets, if
there is - you got a path of length L from the source to the target.
Since the graph is acyclic you can order vertices topologicaly.
Let's name starting vertex A and finish vertex B.
Now the core algorithm starts:
For each vertex count all possible distances from A to this vertex. At start there is
one path from A to A with length zero.
Then take vertices in topological order.
When you pick vertex x: Look at each predecessor and update possible distances here.
This should run in O(N^3) time.
You can use a modified Dijkstra algorithm where instead of saving for every vertex the minimum distance to the origin, you save all the possible distances less or equal to the one desired.
I believe that you can use the following algorithm to find the longest path in a tree. This assumes that your graph is connected, if it is not you would need to rerun this on each connected component:
Pick an arbitrary node, A.
Do a BFS (or DFS) from A to find the node in the tree farthest from A, call this node B.
Do a BFS (or DFS) from B to find the node in the tree farthest from B, call this node C.
The path from B to C is the longest path in the tree (possibly tied for longest).
Obviously if this path is longer than L then you can shorten it to find a path of length L.
Given a directed graph G, what is the best way to go about finding a vertex v such that there is a path from v to every other vertex in G?
This algorithm should run in linear time. Is there an existing algorithm that solves this? If not, I'd appreciate some insight into how this can be solved in linear time (I can only think of solutions that would certainly not take linear time).
Make a list L of all vertices.
Choose one; call it V. From V, walk the graph, removing points from the list as you go, and keeping a stack of unvisited edges. When you find a loop (some vertex you visit is not on the list), pop one of the edges from the stack and proceed.
If the stack is empty, and L is not empty, then choose a new vertex from L, call it V, and proceed as before.
When L is finally empty, the V you last chose is an answer.
This can be done in linear time in the number of edges.
Find the strongly connected components.
Condense each of the components into a single node.
Do a topological sort on the condensed graph, The node with the highest rank will have a path to each of the other nodes (if the graph is connected at all).
I think I've got a correct answer.
Get the SCC.
Condense each of the components into a single node.
Check whether every pair of adjacent nodes is reachable.
This is a sufficient and necessary condition.