Shortest sum of several paths - c++

Let (x,p1,p2,...pn) denote that there is a directed edge from x to p1 (but not from p1 to x), a directed edge from x to p2, etc... and a directed edge from x to pn.
Suppose we have:
(a,b,c)
(b,d,c)
(c,d,e)
(f,e,h)
(g,f,h,i)
(i,j)
For simplicity, let's assume that the distances between all connected nodes are 1. Now there is no connection from a to g or vice versa, but we can have two people leave from a and g respectively and meet at a common point. We want to find the shortest sum of two paths that meet at a node such that one path begins at a and the other begins at g. A simple drawing of this directed graph will reveal that the answer are these two paths:
a->c->e
g->f->e
with a total distance of 4. How to write an algorithm that accepts a directed graph (as in the above) and two nodes (e.g. a and g in this case) and output this answer, which I suppose could be in the form std::make_pair({a,c,e}, {g,f,e})? I tried to adapt Dijkstra's Algorithm to do so but with no luck. I welcomes all ideas.
Edit: Above was a simplified version of the real problem. Here is the real problem, which I was reluctant to describe because an example graph would be too difficult to read. So I will describe it without an example graph.
Two points A and B are selected in a directed graph similar to the one above but larger. There is no connection from one point to the other, and neither is there a common point reachable from both A and B. However, we do know that there exist points (how many is not given) N1, N2, ... Nk such that there is a common point reachable from both A and N1, a common point reachable from both N1 and N2, ..., and a common point reachable from both Nk and B. We want to find these k+1 paths such that the total sum of these paths is minimum. That's the real problem.

You didn't adapt Dijkstra correctly. And you don't have to find dist(a,x) and dist(g,x) for every node x in every case.
In Dijkstra's algorithm, every node is considered Visited or Unvisited, and the search proceeds until the destination is Visited (or no further searching is possible).
In the variant, every node is Unvisited, Visited-By-A, Visited-By-B, or Visited-By-Both. When a node becomes Visited-By-Both, the sum of the paths to it is a limit on the search; the code will keep track of the smallest sum yet found, and terminate the search when the shortest path still being explored is longer than this sum.
I believe this search is O(V logV) in the worst case.
EDIT: The "real" problem.
We have A and B, and we are searching for {N}, {x} that minimizes
(|A, x1| + |N1, x1|) + (|N1, x2| + |N2, x2|) + (|N2, x3| + |N3, x3|)+ ... + (|Nk, xk| + |Nk, B|)
where |x,y| is the length of the shortest path from x to y.
Now consider a new graph, made by adding reverse edges to G: for every edge x->y in G, we add y->x (with the same weight, but all weights are 1 for our purposes) BUT we do not add backward edges leading to A. Then we REMOVE forward edges from B. Now find the shortest path on this new graph from A to B.
This path begins with a forward edge from A, ends with a backward edge to B, and is the shortest such path. Along the path, there must be nodes which the path enters on a forward edge and leaves along a backward edge; we label these xi. And likewise, there must be nodes which the path enters on a backward edge and leaves along a forward edge; we label these Ni. (There must be at least one N, because x1 cannot be xk, because we assume that there is no point forward-reachable from both A and B.)
If we break the path into all-forward and all-backward legs, we get
A-->x1, x1<--N1, N1-->x2, x2<--N2, N2-->x3, ..., xk<--Nk, Nk-->B
The length of this path is
|A,x1| + |N1, x1| + |N1,x2| + |N2,x2| + |N2,x3| + ... + |Nk,xk| + |Nk,B|, which is minimal for this choice of A,B.
Therefore these are the paths we're looking for (and they can be found by a simple O(V) transformation of the graph and a Dijkstra search (O(VlogV))).

Related

Shortest path to cover all edges, in non-weighted, directed graph

Well, I'm facing a problem with a small work I have in hands right now...
The main goal is, having a given graph (without weights, and directed), I have to discover the group of paths(if possible, only one path, but they can be more) with minimum total length, that cover all edges.
Other "constraint" is that the graph, is a DFA, so the paths should start in an initial state, and end in an acceptance state (they're marked).
Initially I found that this was similar to the Chinese Postman Problem, and in fact, it is. But in my case, the graph is directed (I believe this changes thing a bit), and there isn't any problem in processing an edge more than once, since the resultant path remains the shortest.
I've read some things about Euler paths, and T-Joins, and this is probably the solution to my problem. If I understood it right, what I should do is to find an Euler path in my graph and, if there isn't one, make it exist, duplicating the T-Joins, or something like that... I had lots of trouble understanding this, I don't even know if this is the answer to my problem... (shortest and most understandable text I found here: http://en.wikipedia.org/wiki/Route_inspection_problem)
Just to leave a short example, given this graph (1 is initial and 5 is acceptance):
1 -> 2;
2 -> 3;
2 -> 4;
4 -> 5;
The answer to my problem should be: 1 -> 2 -> 4 -> 5 and 1 -> 2 -> 3.
(In this case I would also have to handle the fact that 3 isn't an acceptance state, but that edge had to be covered. But I can easily get through that by flagging all the states with no edges to other nodes as acceptance states).
Hope I explained everything well enough.
Thanks in advance!

The shortest road with 2 ways of transport [duplicate]

Let's say we have two directed and positive-weighted graphs on one set of vertices (first graph represents for example rail-roads and the second one - bus lanes; vertices are bus stops or rail-road stations or both). We need to find the shortest path from A to B, but we can't change the type of transport more than N times.
I was trying to modify the Dijkstra's algorithm, but it's working only on a few "not-so-mean-and-complicated" graphs and I think I need to try something different.
How to best represent that "two-graph" and how to manage the limited amount of changes in traversing the graph? Is there a possibility to adapt Dijkstra's algorithm in this one? Any ideas and clues will be helpful.
Edit: Well I forgot one thing (I think it's quite important): N = 0,1,2,...; we can come up with any graph representation we like and of course there can exist maximum 4 edges between every two nodes (1 bus lane and 1 railroad in one direction, and 1 bus lane and 1 railroad in the second direction).
I don't think it is the best way, but you can create Nodes as follow:
Node:(NodeId, GraphId, correspondenceLeftCount)
(the total number of nodes will be number_of_initial_nodes * number_of_graphs * number_of_correspondences_allowed)
So:
For edge where GraphId doesn't change, correspondenceLeftCount doesn't change neither.
You add a new Edge for correspondance:
(NodeId, Graph1, correspondenceLeftCount) -> (NodeId, Graph2, correspondenceLeftCount - 1)`
And for the request A->B:
Your start point are (A, graph1, maxCorrespondenceLeftCount) and (A, graph2, maxCorrespondenceLeftCount).
And your end points are (B, graph1, 0), ... , (B, graph1, maxCorrespondenceLeftCount), (B, graph2, 0), ... , (B, graph2, maxCorrespondenceLeftCount).
So you may to have to adapt your Dijkstra implementation for the end condition, and to be able to insert more than one start point.

Minimum cost to visit only selected cities and come back to start?

I understand the travelling salesman problem. Suppose if I want to visit only selected cities and come back to start, how to do that?
Lets say my cost matrix is,
A B C D
A 0 1 2 1
B 1 0 1 2
C 2 1 0 1
D 1 2 1 0
If I want to visit all the cities and come back to A. My shortest path would be A->B->C->D and min distance would be 4.
Suppose lets say if I want to visit only B and D. How can I find the min distance?
This is modified travelling salesman problem? Can someone help me with doing brute force algo for this case?
You can run first Floyd-Warshall to compute the shortest paths between all pairs of nodes. See wikipedia article.
Once you have the condensed cost matrix you can eliminate all cities that you are not interested in. From there it's the standard traveling salesman.
Since traveling salesman is NP complete it doesn't matter for complexity that you run Floyd-Warshall before it.
If you want the complete directions (including detours through uninteresting cities to make the paths shorter you'll have to go back to the Floyd-Warshall and reconstruct the paths.
I don't have my code handy, but here's some suggestions and pseudocode to get you going:
I would solve this by storing a vector as well as your above distance matrix in memory. Something like:
struct Location{
bool visited;
bool mustVisit;
}
Vector<Location> locationVec;
Populate the vector with the locations in your problem, marking whether or not they have to be visited, and always setting visited to false. Then comes the fun part! You need to create permutations of the locationVec. I would do this recursively, something like:
void addLocation(int & curLength, int & maxLength, int & curDistance, Vector<Location> &locationVec, Location* lastVisited)
if(curLenth == maxLength){
//check if currentDistance is less than the previously generated best difference, if so
//replace it
lastVisited->visited=0;
return;
}
//Add the next location
for (int& i : locationVec){
//Check if the location has been visited, and if it must be visited.
//If so: mark as visited, point lastVisited to it, and break
//Also add from lastVisited to the new location to your curDistance
curLength++;
}
addLocation(curLength, maxLength, curDistance, locationVec, lastVisited);
return;
}
That should get you started. Remember to subtract from currentDist when you change visited from visited = 1 to visited = 0, because you're essentially "unvisiting" the city. You may need to keep track of lastlastvisited as well, depending on your exact implementation.
If you need to speed it up (and you probably will, traveling Salesman is very slow), look into Branch and Bound: http://en.wikipedia.org/wiki/Branch_and_bound

Partition in Equivalence sets

I have a simple, non-dirictional tree T. I should find a path named A and another named B that A and B have no common vertex. The perpuse is to maxmize the Len(A)*Len(B).
I figured this problem is similer to Partition Problem, except in Partition Problem you have a set but here you have a Equivalence set. The solution is to find two uncrossed path that Len(A) ~ Len(B) ~ [n-1/2]. Is this correnct? how should I impliment such algorithm?
First of all. I Think you are looking at this problem the wrong way. As I understand it you have a graph related problem. What you do is
Build a maximum spanning tree and find the length L.
Now, you say that the two paths can't have any vertex in common, so we have to remove an edge to archieve this. I assume that every edge wheight in your graph is 1. So sum of the two paths A and B are L-1 after you removed an edge. The problem is now that you have to remove an edge such that the product of len(a) and len(b) is maximized. You do that by removeing the edge in et most 'middel' of L. Why, the problem is of the same as optimizing the area of a rectangle with a fixed perimeter. A short youtube video on the subject can be found here.
Note if your edge wheights are not equal to 1, then you have a harder problem, because there may exist more than one maximum spanning tree. But you may be able to split them in different ways, if this is the case, write me back, then I will think about a solution, but i do not have one at hand.
Best of luck.
I think there is a dynamic programming solution that is just about tractable if path length is just the number of links in the paths (so links don't have weights).
Work from the leaves up. At each node you need to keep track of the best pair of solutions confined to the subtree with root at that node, and, for each k, the best solution with a path of length k terminating in that node and a second path of maximum length somewhere below that node and not touching the path.
Given this info for all descendants of a node, you can produce similar info for that node, and so work your way up to the route.
You can see that this amount of information is required if you consider a tree that is in fact just a line of nodes. The best solution for a line of nodes is to split it in two, so if you have only worked out the best solution when the line is of length 2n + 1 you won't have the building blocks you need for a line of length 2n + 3.

The New Villa Acm solution strategy

I am trying to solve this ACM problem The New Villa
and i am not figuring out how to approach this problem definitely its graph problem but doors and the room that have switches to other rooms are very confusing to make a generic solution. Can some body help me in defining the strategy for this problem.
Also i want some discussion forum for ACM problems if you know any one then please share.
Thanks
A.S
It seems like a pathfinding problem on states.
You can represent each vertex with a binary vector of size n + an indentifier - where which room you are in at the moment [n is the number of rooms].
G=(V,E) where V = {all binary vectors of size n and a recored for which room you are in} and E = {(u,v) | you can switch from binary vector u to v by clicking a button in the room you are in, or move to adjacent lights on room }
Now you only need to run a search algorithm on the possible paths.
Possible search algorithms:
BFS - simplest to program, though slowest run time
bi - directional BFS - since there is only one target node,
a bi-directional search will work here, it is expected to be much
faster then BFS
A* - find an admissible heurstic function and run
informed A* on the problem. It is harder to program it then the rest - but if you find a good heurisitc, it will most likely perform much better.
(*) All of the above are both complete [will find a solution if one exists] and optimal [will find the shortest solution, if one exists]
(*) This solution runs in exponential time on the number of rooms, but it should end up for d <= 10 as indicated in the problem in reasonable time.