How can I modify Dijkstra's algorithm to get the longest path most of the time? - graph-algorithm

I know that finding the longest path is an NP Hard problem.
What was asked from us was to change Dijkstra's algorithm to find the longest path by adding another parameter to the algorithm. A parameter like the distance from the source to the given vertex, the vertex predecessors, successors, number of edges...For example, we could extract the vertex from the queue depending on a parameter other than the max distance or we could another queue...
What we did first was to change the initialization so that all vertices distances = 0 except the source node, that = infinity. Then we extracted from the queue of vertices the one with the biggest distance. Then, we inverted the relaxation sign, so that the vertex saves the distance if it is bigger that its current distance.
What parameter could I add that would improve Dijkstra's performance in finding a longest path? It doesn't have to work 100% of the time.
This is Dijkstra's algorithm:
ShortestPath(G, v)
init D array entries to infinity
D[v]=0
add all vertices to priority queue Q
while Q not empty do
u = Q.removeMin()
for each neighbor, z, of u in Q do
if D[u] + w(u,z) < D[z] then
D[z] = D[u] + w(u,z)
Change key of z in Q to D[z]
return D as shortest path lengths
This is our modified version:
ShortestPath(G, v)
init D array entries to 0
D[v]=infinity //source vertex
add all vertices to priority queue Q
while Q not empty do
u = Q.removeMax()
for each neighbor, z, of u in Q do
if D[u] + w(u,z) > D[z] then
D[z] = D[u] + w(u,z)
Change key of z in Q to D[z]
return D as shortest path lengths

Related

Line Follower based on Image Processing

I’m starting to work on a line follower project but it is required that I use image processing techniques. I have a few ideas to consider, but I would like some input as there are some doubts I would like to clarify. This is my approach to solve this problem: I first read the image, then apply thresholding to detect the object (the line). I do color filtering and then edge detection. After this I start to do image classification to detect all the lines, then extrapolate those lines to only output/detect parallel lines (like a lane detection algorithm). With this parallel lines I can calculate the center to maintain my vehicle centered and the angle to make turns.
I do not know the angles in the path so the system must be able to turn any angle, that’s why I will calculate the angle. I have included a picture of a line with a turn, this is the kind of turns I will be dealing with. I have managed to implement almost everything. My main problem is in the change of angle, basically the turns. After I have detected the parallel lines, how can I make my system know when is time to make a turn? The question might be kind of confusing, but basically the vehicle will be moving forward as long the angle is near to zero. But when the vehicle approach a turn, it might detect two set of parallel lines. Maybe I can define a length of the detected lines that will define whether or not the vehicle must move forward?
Any ideas would be appreciated.
If you have two lines (the center line of each path):
y1 = m1 * x + b1
y2 = m2 * x + b2
They intersect when you choose an x such that y1 and y2 are equal (if they are not parallel of course, so m1 != m2)
m1 * x + b1 = m2 * x + b2
(do a bunch of algebra)
x = (b2 - b1) / (m1 - m2)
(y should be the same for both line formulas)
When you are near this point, switch lines.
NOTE: This won't handle the case of perfectly vertical lines, because they have infinite slope, and no y-intercept -- for that see the parametric form of lines. You will have 2 equations per line:
x = f1(t1)
y = f2(t1)
and
x = f3(t2)
y = f4(t2)
Set f1(t1) == f3(t2) and f2(t1) == f4(t2) to find the intersection of non-parallel lines. Then plug t1 into the first line formula to find (x, y)
Basically the answer by Lou Franco explains you how to get the intersection of the two center line of each path and then that intersection is a good point to start your turn.
I would add a suggestion on how to compute the center line of a path.
In my experience, when working with floating point representation of lines extracted from images, the lines are really never parallel, they just intersect usually at a point that falls out of the image (maybe far away).
The following C++ function bisector_of_lines is inspired by the method bisector_of_linesC2 found at CGAL source code.
A line is expressed as a*x+b*y+c=0, the following function
constructs the bisector of the two lines p and q.
line p is pa*x+pb*y+pc=0
line q is qa*x+qb*y+qc=0
The a, b, c of the bisector line are the last three parameters of the function: a, b and c.
In the general case, the bisector has the direction of the vector which is the sum of the normalized directions of the two lines, and which passes through the intersection of p and q. If p and q are parallel, then the bisector is defined as the line which has the same direction as p, and which is at the same distance from p and q (see the official CGAL documentation for CGAL::Line_2<Kernel> CGAL::bisector).
void
bisector_of_lines(const double &pa, const double &pb, const double &pc,
const double &qa, const double &qb, const double &qc,
double &a, double &b, double &c)
{
// We normalize the equations of the 2 lines, and we then add them.
double n1 = sqrt(pa*pa + pb*pb);
double n2 = sqrt(qa*qa + qb*qb);
a = n2 * pa + n1 * qa;
b = n2 * pb + n1 * qb;
c = n2 * pc + n1 * qc;
// Care must be taken for the case when this produces a degenerate line.
if (a == 0 && b == 0) {// maybe it is best to replace == with https://stackoverflow.com/questions/19837576/comparing-floating-point-number-to-zero
a = n2 * pa - n1 * qa;
b = n2 * pb - n1 * qb;
c = n2 * pc - n1 * qc;
}
}

How to use segment tree and scanline

Given 300000 segments.
Consider any pair of segments: a = [l1,r1] and b = [l2,r2].
If l2 >= l1 and r2 <= r1 , it is "good" pair.
If a == b, it is "bad" pair.
Overwise, it is "bad" pair.
How to find number of all "good" pairs among given segments using segment tree and scanline?
Sort the segments in increasing order with respect to their l-values and for pairs with same l-values sort them in decreasing order with respect to their r-value.
Suppose for a particular , you want to count the number of good pairs (ai,aj) such that j < i. Let ai=[l1,r1] and aj = [l2,r2]. Then we have l2 <= l1. Now we need to count all the possible values of j such that r2 <= r1. This can be done by maintaining a segment tree for the values of r for all j such that 0 < j < i. After querying for the i-th pair, update the segment tree with the r-value of the i-th segment.
Coming to segment tree part, build a segment tree on the values of r. On updating a value of r in segment tree, add 1 to the value of r in the segment tree and for querying for a particular value of r, query for sum in the range [0,r-1]. This will give total number of segments that fit good with the given segment.
If the values of r are big that would not fit into segment tree, then apply coordinate compression to values first and then use segment tree for the compressed values.

minimum weight shortest path for all pairs of vertices with exactly k blue edges

Basically a subset of the graph has edges which are blue
So I know how to find all pairs shortest paths with DP in O(n^3), but how do I account for color and the exactness of the number of edges required for the problem?
This can be done in O(k^2 . n^3) using a variant of Floydd-Warshall.
Instead of keeping track of the minimum path weight d(i,j) between two nodes i and j, you keep track of the minimum path weight d(i,j,r) for paths between i and j with exactly r blue edges, for 0 ≤ r ≤ k.
The update step when examining paths through a node m, where normally d(i,j) would be updated with the sum of d(i,m) and d(m,j) if it is smaller, becomes:
for u: 0 .. k
for v: 0 .. (k-u)
s = d(i,m,u) + d(m,j,v)
d(i,j,u+v) = min( s, d(i,j,u+v) )
At the end, you then read off d(i,j,k).

Maximal path problem

Given oriented unweighted graph and the problem is to find simple path of maximal length
(start vertex and end vertex are not fixed). It obviously can be solved in O(n^2 * 2 ^n) but I heard that there is O(n * 2 ^ n) algorithm which I don't know. So how to solve it in O(n * 2 ^n)? //n = |V|
If your problem really is the Longest Path Problem on a DAG, the algorithm from Wikipedia is below and runs in O(|V| + |E|):
algorithm dag-longest-path is
input:
Directed acyclic graph G
output:
Length of the longest path
length_to = array with |V(G)| elements of type int with default value 0
for each vertex v in topOrder(G) do
for each edge (v, w) in E(G) do
if length_to[w] <= length_to[v] + weight(G,(v,w)) then
length_to[w] = length_to[v] + weight(G, (v,w))
return max(length_to[v] for v in V(G))

Cascaded Hough Transform in OpenCV

Is it possible to perform a Cascaded Hough Transform in OpenCV? I understand its just a HT followed by another one. The problem I'm facing is that the values returned are always rho and theta and never in y-intercept form.
Is it possible to convert these values back to y-intercept and split them into sub-spaces so I can detect vanishing points?
Or is it just better to program an implementation of HT myself in, say, Python?
you could try to populate the Hough domain with m and c parameters instead, so that y = mx + c can be re-written as c = y - mx so instead of the usual rho = x cos(theta) + y sin(theta), you have c = y - mx
normally, you'd go through the thetas and calculate the rho, then you increment the accumulator value for that pair of rho and theta. Here, you'd go through the value of m and calculate the values of c, then accumulate that m,c element in the accumulator. The bin with the most votes would be the right m,c
// going through the image looking for edge pixels
for (i = 0;i<numrows;i++)
{
for (j = 0;j<numcols;j++)
{
if (img[i*numcols + j] > 1)
{
for (n = first_m;n<last_m;n++)
{
index = i - n * j;
accum[n][index]++;
}
}
}
}
I guess where this becomes ineffective is that its hard to define the step size for going through m as they should technically go from -infinity to infinity so you'd kind of have trouble. yeah, so much for Hough transform in terms of m,c. Lol
I guess you could go the other way and isolate m so it would be m = (y-c)/x so that now, you cycle through a bunch of y values that make sense and its much more manageable though it's still hard to define your accumulator matrix because m still has no limit. I guess you could limit the values of m that you would be interested in looking for.
Yeah, much more sense to go with rho and theta and convert them into y = mx + c and then even making a brand new image and re-running the hough transform on it.
I don't think OpenCV can perform cascaded hough transforms. You should convert them to xy space yourself. This article might help you:
http://aishack.in/tutorials/converting-lines-from-normal-to-slopeintercept-form/

Resources