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.
Related
I have the following task, but I have no idea how to do it?
Calculate (lexicographically) the shortest path from V1-node to the other nodes by means of Dijkstra. Please write the current Heaps and corresponding Pred-fields as well. Start with new Heap and pred-field before the ExtractMin-Call.
I got this result via Dijkstra, but how should I add it to the min-heap (tree)?
I found exactly this task in an old exam I use for learning algorithms. I wasn't sure how to solve it so I searched several books for any explanation on how the minheap works along with Dijkstra and didn't find any. Finally I figured it out. So I hope this helps to understand how to solve this problem.
Step 1: Draw the heap lexicographically: V1 -> root, and then the
other nodes from left to right. V1 has the value 0, all other nodes
inf.
Step 2: ExtractMin(): swap root (which has the lowest value)
with the very last node and cut it off.
Step 3: Relaxation: Update new values for the nodes, if value decreases. "What is the new value from start to X when
I walk via the node, I just extracted, respecting its predecessors? Is it less than the old value, then update."
Step 4: Update the predecessor field if there is a better path.
Step 5: Call Heapify(): Resort the heap, so that
the node with the lowest value becomes root.
Repeat Step 2 to 5 until there are no nodes left.
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 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.
Im wondering if I can optimize my pathfinding code a bit, lets look at this map:
+ - wall, . - free, S - start, F - finish
.S.............
...............
..........+++..
..........+F+..
..........+++..
...............
The human will look at it and say its impossible, becouse finish is surrounded... But A-star MUST check all fields to ascertain, that there isnt possible road. Well, its not a problem with small maps. But when I have 256x265 map, it takes a lot of time to check all points. I think that i can stop searching while there are closed nodes arround the finish, i mean:
+ - wall, . - free, S - start, F - finish, X - closed node
.S.............
.........XXXXX.
.........X+++X.
.........X+F+X.
.........X+++X.
.........XXXXX.
And I want to finish in this situation (There is no entrance to "room" with finish). I thought to check h, and while none of open nodes is getting closer, then to finish... But im not sure if its ok, maybe there is any better way?
Thanx for any replies.
First of all this problem is better solved with breadth-first search, but I will assume you have a good reason to use a-star instead. However I still recommend you first check the connectivity between S and F with some kind of search(Breadth-first or depth-first search). This will solve our issue.
Assuming the map doesn't change, you can preprocess it by dividing it to connected components. It can be done with a fast disjoint set data structure. Then before launching A* you check in constant time that the source and destination belong to the same component. If not—no path exists, otherwie you run A* to find the path.
The downside is that you will need additional n-bits per cell where n = ceil(log C) for C being the number of connected components. If you have enough memory and can afford it then it's OK.
Edit: in case you fix n being small (e.g. one byte) and have more than that number of components (e.g. more than 256 for 8-bit n) then you can assign the same number to multiple components. To achieve best results make sure each component-id has nearly the same number of cells assigned to it.