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.
Related
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))).
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!
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.
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.
In this link ( Meta Interpreter ) I believe to have found a nifty way of solving a problem I have to tackle, but since my prolog is very bad I'd first ask if its even possible what I have in mind.
I want to transform certain parts of a workflow/graph depending on a set of rules. A graph basically consists of sequences (a->b) and split/joins, which are either parallel or conditional, i.e. two steps run in parallel in the workflow or a single branch is picked depending on a condition (the condition itself does not matter on this level) (parallel-split - (a && b) - parallel-join) etc. Now a graph usually has nodes and edges, with the form of using terms I want to get rid of edges.
Furthermore each node has a partner attribute, specifying who will execute it.
I'll try to give a simple example what I want to achieve:
A node called A, executed by a partner X, connected with a node called B, executed by a partner Y.
A_X -> B_Y
seq((A,X),(B,Y))
If I detect a pattern like this, i.e. two steps in sequence with different partners, I want this to be replaced with:
A_X -> Send_(X-Y) -> Receive_(Y-X) - B_Y // send step from X to Y and a receive step at Y waiting for something from X
seq((A,X), seq(send(X-Y), seq(receive(Y-X), B)))
If anyone could give me some pointers or help to come up with a solution I would be very thankful!
A graph basically consists of sequences (a->b) and split/joins, which are either parallel or conditional, i.e. two steps run in parallel in the workflow or a single branch is picked depending on a condition
This sounds an awful lot like an and/or graph. Prolog algorithms on these graphs are covered by Ivan Bratko in Prolog Programming for Artificial Intelligence, chapter 13. Even if your graphs aren't really and/or graphs, you may be able to adapt some of these algorithms to your task.