I have a directed graph with weighted edges (weights are all positive).
Now, I'm looking for an efficient algorithm or code (specifically, C#) to find the longest path between two given vertices.
This is exactly equivalent to a shortest-path algorithm with all negative weights. To do that, you need to verify that there are no negative-weight cycles (which in your original case is probably equivalent to verifying no positive-weight cycles). Best bet is to take the additive inverse of the weights and run Bellman-Ford, then take the additive inverse of the result.
David Berger's answer is correct, unless you mean a simple path, where each vertex can occur at most once, in which case Bellman-Ford will not give the longest path. Since you say the weights are positive, it's not possible for a longest path to exist when the graph has a cycle (reachable from the source), unless you mean simple path. The longest simple path problem is NP-complete. See Wikipedia.
So, let's assume you mean a directed acyclic graph (DAG). In linear time, you can compute the longest path to each vertex v from the start vertex s, given that you know the longest path from s->*u for each u where u->v directly. This is easy - you can do a depth first search on your directed graph and compute the longest path for the vertices in reverse order of visiting them. You can also detect back edges whole you DFS using a 3-color marking (opened but not finished vertices are gray). See Wikipedia again for more information. Longest/shortest path finding on a DAG is sometimes called the Viterbi algorithm (even though it was given assuming a specific type of DAG).
I'd attempt the linear time dynamic programming solution first. If you do have cycles, then Bellman-Ford won't solve your problem anyway.
Please refer to the QuickGraph project as it provides .NET data structures implementing graphs, and also provides algorithms to operate on such data structures. I'm certain the algorithm you are looking for is implemented in the library.
Just in case it helps anyone, as I was looking for this for a while but couldn't find it, I used QuickGraph to solve a problem where I had to find the longest path that also complies with a certain rule. It is not very elegant as I did it a bit on brute force once I get the first result, but here it is.
https://github.com/ndsrf/random/blob/master/LongestSkiPath/LongestSkiPath/SkiingResolver.cs#L129-L161
To get the longest path you use an algorithm to find the shortest with lenghts = -1. And then to find subsequent longest paths I start removing edges from that longest path to see if I manage to get a "better" (based on the conditions of the problem) longest path.
Related
I have two sets of points, A and B, and I'm trying to find the closest pair of points where one point is taken from each set. That is, if you were to use the points two draw to lines, I want the two points that allow me to draw the shortest line segment between the two lines.
Looking around, almost everything seems to deal with finding the closest points in 1 set. Although I did find one solution recommending voronoi tesselation to begin with, which seems a bit like overkill, I'm just looking for something a bit nicer than O(n^2).
If it helps, the two sets I'm comparing form lines, although they are not necessarily straight and I'm writing this in C#.
Thanks.
It should be possible to adapt the classical D&C algorithm (as described in the Wikipedia link), by processing all points together and tagging them with an extra bit.
The merging step needs to be modified to accept candidate left-right pairs with a member from every set only. This way, the recursive function will return the closest A-B pair. The O(N.Log(N)) behavior should be preserved.
If the "lines" you mention have a known equation so that point/line distances (or even line/line intersections) can be evaluated quickly, there could be faster solutions.
I am having trouble implementing this into my current path finding algorithm.
Currently I have Dijkstra written and works like it should, but I need to step further away and add a limit (range). I can better explain with an image:
Let's say I have range of 80. I want to go from A to E. My current algorithm, works as it should, so it results in A->B-E.
However, I need to go only on paths with weight not more than the range - 80, which would mean that A->B->E is not the option any more, but A->C->D->B->E (considering that range/limit resets on every stop)
So far, I have implemented a bool named Possible which would return for the single part of path (e.g. A->B) is it possible comparing to my limit / range.
My main problem is that I do not know where/how to start. My only idea was to see where Possible is false (A->B on the total route A->B->E) and run the algorithm from A to A->E again without / excluding B stop/vertex.
Is this a good approach? Because of that my big O notation would increment twice (as far as I understand it).
I see two ways of doing this
Create a new graph G' that contains only edges < 80, and look for shortest path there... reduction time is O(V+E), and additional O(V+E) memory usage
You can change Dijkstra's algorithm, to ignore edges > 80, just skip edges >80, when giving values to neighbor vertices, the complexity and memory usage will stay the same in this case
Create a temporary version of your graph, and set all weights above the threshold to infinity. Then run the ordinary Dijkstra algorithm on it.
Complexity will increase or not, depending on your version of the algorithm:
if you have O(V^2) then it will increase to O(E + V^2)
if you have the O(ElogV) version then it will increase to O(E + ElogV)
if you have the O(E + VlogV) version it will remain the same
As noted by ArsenMkrt you can as well remove these edges, which makes even more sense but will make the complexity a bit worse. Modifying the algorithm to just skip those edges seems to be the best option though, as he suggested in his answer.
For an assignment for school I have to make a solver for a Rush Hour game.. if you aren't familiar with Rush Hour.. check this link: http://www.puzzles.com/products/rushhour.htm
For this solver I have to use the A* search algorithm, I looked on the internet a bit, and I think I quite understood how the algorithm works.. only I don't really have an idea how to implement it in the solver.. nor how I should build up the grid for the cars.. Can someone please give me some tips/help for this?
Not a complete solution..
To represent the grid of cars, I'd just use a rectangular array of cells where each cell is marked with an integer -- 0 indicates "empty", and each car has a particular number, so the different cars in the grid will manifest themselves as consecutive cells with the same number.
At this point, you should be able to write a function to return all the possible "moves" from a given grid, where a "move" is a transition from one grid state to another grid state -- you probably don't need to encode a better representation of a move than that.
To implement A*, you'll need a naive heuristic for figuring out how good a move looks, so you know which moves to try first. I would suggest initially that any move which either moves the target car closer to the goal or makes space nearer the front of the target car might be a better candidate move. Like Will A said in the comments, unless you're solving a 1000x1000 Rush Hour board, this probably isn't a big deal.
That's all the tricky parts I can think of.
As mquander or Will have already pointed out, the A* algorithm might be a bit an overfit for your problem.
I just give you now some hints what other algorithm you can use to solve the problem.
I don't want to explain how those algorithms work since you can find many good description in the internet. However, if you have a question, don't hesitate to ask me.
You can use some algorithms which belong to the kind of "uninformed search". There you have for example breadth first search, deep-first search, uniform cost search, depth-limited search or iterative deepening search. If you use breadth-first search or uniform cost search then you might have to deal with available memory space problem since those algorithms have an exponential space complexity (and you have to keep the whole search space in memory). Therefore, using a deep-first search (space complexity O(b*m)) is more memory friendly since the left part of the tree which you visit firstly can be omitted if it does not contain the solution. Depth-limited search and iterative deepening search are almost the same, whereas in the iterative deepening search you increase the search level of your tree iteratively.
If you compare time complexity (b=branching factor of the tree, m=maximum depth of the tree, l=depth level limit, d=depth of the solution):
breadth-first: b^(d+1)
uniform cost: b^?
depth-fist:b^m
depth-limited: b^l if (l>d)
iterative deepening: b^d
So as you can see iterative deepening or breadth-first search perform quite well. The problem of the depth-limited search is if your solution is located deeper than you search level, then you will not find a solution.
Then you have the so called "informed search" such as best-first search, greedy search, a*, hill climbing or simulated annealing. In short, for the best-first search, you use an evaluation function for each node as an estimate of “desirability". The goal of the greedy search is to expand the node which brings you closer to goal. Hill climbing and simulated annealing are very similar. Stuart Russell explains hill climbing as following (which I like a lot...): the hill climbing algorithm is like climbing Everest in thick fog with amnesia". It is simply a loop that continually moves in the direction of increasing value. So you just "walk" to the direction which increases your evaluation function.
I would use one of the uniformed search algorithms since they are very easy to implement (you just need to programme tree and traverse it correctly). Informed search performs usually better if you have a good evaluation function...
Hope that helps you...
I am witting a project of image processing.
For some part of my project to find good threshold value I need to find peaks and valleys of image's histogram.
I am witting my project in C# .net
but I need Algorithm or sample code in any languages like(Java, C,C++,....) to understand the logic of that. I can convert to C# by my self.
any document or algorithm or piece of code...
thanks
It's hard to beat Ohtsu's Method for binary thresholding. Even if you insist on implementing local extrema searching by yourself, Ohtsu's method will give you a good result to compare to.
If you already have computed your histogram, to find peaks and valleys is computationally trivial (loop over it and find local extrema). What is not trivial is to find "good" peaks and valleys to do some segmentation/threshold. But that is not a matter of coding, it's a matter of modelling. You can google for it.
If you want a simple recipe, and if you know that your histogram has "essentially" two peaks and a valley in the middle ("bimodal" histogram) and you want to locate that valley, I have once implemented the following ad-hoc procedure, with relative success:
Compute all the extrema of the histogram (relative maxima/minima, including borders)
If there are only two maxima, AND if in between those maxima there is only one local minimum, we've found the valley. Return it.
Else, smooth the histogram (eg. a moving average) and go to first step.
I found an interesting pairs matching game at http://xepthu.uhm.vn. The rule is simple, you have to find and connect two identical pokemon but the path between them is not blocked and the direction can't not be changed 3 times. Let's see an example:
I've think alot about the algorithm to check if the path between any 2 selected pokemon is valid but because I'm a newbie so I can't find any solution. Can you suggest me one in C#?
This is basically a path finding problem from graph theory. The fields in the grid are the nodes, and all adjacent fields are connected by an edge.
Path finding is a well-known problem, and there are many algorithms that solve this. Since your graph is quite small, the best solution here is probably just a brute force algorithm. A popular path finding algorithm is Dijkstra's algorithm.
Brute force: Start at some pokemon and explore all possible ways to see if one leads to an identical pokemon. You can stop exploring a way if the way is blocked or has more than 2 turns.
You'll need some "pointer" pointing to a field in the grid. The pointer can move left, right, up or down, provided that the field in that direction is not blocked. Move the pointer to an adjacent field. Remember where you came from and how many turns you made. Repeat this until you've reached your destination. Backtrack if the number of turns reaches 3. Make sure you don't run in circles.
Take a look at planar graphs. You will have to introduce a second condition: no more than four nodes may be traversed (start node - first direction change - second direction change - end node).