Shortest paths problem with one alteration - c++

Let's say i have a directed graph G(V,E) with positive integer weights at it's edges.What i need to do is find the shortest paths between all vertices using at most K(integer) reverse edges.What i mean by that is:If we are at edge u and there is only a directed edge from v to u we can use it as long as we have not used K reverse edges for this path.This has to be implemented in C++ and give the shortest paths as a result.
I think the main approach to this problem is to conceptually create K+1 copies of the graph where each copy has one reverse edge,copy G_0 has one G_1 two etc.I could then run dijkstra in this graph and find the shortest path from a vertex to all others using as much as K reversed edges.This could be done V times(like johnsons algorithm)to find all possible shortest paths.My question is:how could this be implemented in c++?I excpect we don't have to create this multigraph but i can't see how it can be done otherwise.

If you know Dijkstra, you know that every vertex has a tentative distance label (initially infinite, except for the source) and you process the vertices in order of that tentative distance by "relaxing" their arcs, that is, updating the tentative distances of their neighbors.
If you allow for a number of arcs to be travelled in the wrong direction, I would go for a dynamic programming approach and have K labels for each vertex with the following semantics: Label 0 is the classic Dijstra label, Label 1 is the minimum distance from the start on a path with at most one reverse arc and so on.
Now, if I am correct, all you got to do is start with infinite labels and labels 0 for the source. Process labels instead of arcs and (again) start with the minimum tentative distance.
In contrast to the original, relaxing reverse arcs is allowed, but will update the K+1 label of the other side of the arc, while relaxing arcs in their normal direction will update the Kth label.

Related

Given a start and goal ,how to find the shortest way in a navigation mesh?

I googled "A* algorithm on navigation mesh" only to get wrong ways to estimate g-values,like this
or this
By summing up the length of the blue line segments ,we get the g-value ,but it's overestimated (g-value should be underestimated). This algorithm will return a optimized path ,but not guaranteed to be the shortest.
The only way I can think of is to draw a visibility graph based on the navigation mesh .But that would cost too much memory .
Are there any other ways to calculate the shortest way in a navigation mesh ?
To get a shortest path closer from what you mean, you should stop using fix points as A-star nodes i.e. stop using center of triangles or center of triangles'edge.
Try to move the points as the A-star propagates.
For instance, use A-star nodes on triangles'edge which are :
either the intersection of the triangle's edge of next A-star node with the segment formed by previous A-star node and the destination
or the closest point from the intersection mentioned above on the triangle's edge of next A-star node
Or, try to change the path nodes after computing your A-star as currently done, using similar criteria.
Note that this will smooth the final path (as the red line on your drawings).
But this will only help reducing the overestimation, this doesn't guarantee finding the shortest paths as you meant it.
Better, try to change the path nodes after computing your A-star using center of triangles'edges, using string pulling a.k.a funnel algorithm. This will give you the shortest path through the triangles traversed by the output path of the A-star.
A*-search algorithm is a performance modification of Dijkstra algorithm and gives you only an approximation of the shortest path by considering only edge-paths (in primary or in dual graph):
After that the path has to be optimized and converted into geodesic path by allowing it to cross arbitrary any mesh triangle:
See, for example, answers to this question for details.
The pictures above were made in MeshInspector application.

Maze least turns

I have a problem that i can't solve.I have a maze and I have to find a path from a point S to a point E,which has the least turns.It is known that the point E is reacheable.I can move only in 4 directions,left,right,up and down.It doesn't have to be the shortest path,just to have least turns.
I tried to store the number of turns in a priority queue.For example when I reach a certain place in the maze I will add the numbers of turns till there.From there I would add his neighbours to the priority queue,if they weren't visited already or they weren't walls,with the value of the current block i was sitting,for example t + x which can have the following values ( 0-if the neighbour is facing in the same direction I was facing when i got near him,or 1 if it is in a different direction).It seems that this approach doesn't work for every case.
I will appreciate if somebody could offer me some hints, without any code.
You are on the right track. What you need to implement for this problem is Dijkstra's algorithm. You just need to consider not just points as graph vertices, but pair of (point,direction). From every vertex (p,d) you have 5 edges (although last one can be blocked by wall): (p,0), (p,1), (p,2), (p,3), (neighbour of p in direction d, d). First four edges are of weight 1 (as you turn here), and the last one is of weight 0 (no turn, just move forward). Algorithm is good enough to ignore loops and works fine for edges of weight 0. You should end when any vertex (end point, _) is extracted from priority queue.
This method has one issue, as too many verticies are inspected in the process. If your maze is small, that's not the problem. Otherwise, consider a slight modification known as A*. You need a good heuristic function, describing lower bound on number of turns to the goal.

Shortest path graph algorithm help Boost

I have a rectangular grid shaped DAG where the horizontal edges always point right and the vertical edges always point down. The edges have positive costs associated with them. Because of the rectangular format, the nodes are being referred to using zero-based row/column. Here's an example graph:
Now, I want to perform a search. The starting vertex will always be in the left column (column with index 0) and in the upper half of the graph. This means I'll pick the start to be either (0,0), (1,0), (2,0), (3,0) or (4,0). The goal vertex is always in the right column (column with index 6) and "corresponds" to the start vertex:
start vertex (0,0) corresponds to goal vertex (5,6)
start vertex (1,0) corresponds to goal vertex (6,6)
start vertex (2,0) corresponds to goal vertex (7,6)
start vertex (3,0) corresponds to goal vertex (8,6)
start vertex (4,0) corresponds to goal vertex (9,6)
I only mention this to demonstrate that the goal vertex will always be reachable. It's possibly not very important to my actual question.
What I want to know is what search algorithm should I use to find the path from start to goal? I am using C++ and have access to the Boost Graph Library.
For those interested, I'm trying to implement Fuchs' suggestions from his Optimal Surface Reconstruction from Planar Contours paper.
I looked at A* but to be honest didn't understand it and wasn't how the heuristic works or even whether I could come up with one!
Because of the rectangular shape and regular edge directions, I figured there might be a well-suited algorithm. I considered Dijkstra
but the paper I mention said there were quicker algorithms (but annoyingly for me doesn't provide an implementation), plus that's
single-source and I think I want single-pair.
So, this is your problem,
DAG no cycles
weights > 0
Left weight < Right weight
You can use a simple exhaustive search defining every possible route. So you have a O(NxN) algoririthm. And then you will choose the shortest path. It is not a very smart solution, but it is effective.
But I suppose you want to be smarter than that, let's consider that if a particular node can be reached from two nodes, you can find the minimum of the weights at the two nodes plus the cost for arriving to the current node. You can consider this as an extension of the previous exhaustive search.
Remember that a DAG can be drawn in a line. For DAG linearization here's an interesting resource.
Now you have just defined a recursive algorithm.
MinimumPath(A,B) = MinimumPath(MinimumPath(A,C)+MinimumPath(A,D)+,MinimumPath(...)+MinimumPath(...))
Of course the starting point of recursion is
MinimumPath(Source,Source)
which is 0 of course.
As far as I know, there isn't an out of the box algorithm from boost to do this. But this is quite straightforward to implement it.
A good implementation is here.
If, for some reason, you do not have a DAG, Dijkstra's or Bellman-Ford should be used.
if I'm not mistaken, from the explanation this is really an optimal path problem not a search problem since the goal is known. In optimization I don't think you can avoid doing an exhaustive search if you want the optimal path and not an approximate path.
From the paper it seems like you are really subdividing a space many times then running the algorithm. This would reduce your N to closer to a constant in the context of the entire surface making O(N^2) not so bad.
That being said perhaps dynamic programming would be a good strategy where the N would be bounded by the difference between your start and goal node. Here is an example form genomic alignment. Just an illustration to give you an idea of how it works.
Construct a N by N array of cost values all set to 0 or some default.
#
For i in size N:
For j in size N:
#cost of getting here from i-1 or j-1
cost[i,j] = min(cost[i-1,j] + i edge cost , cost[i,j-1] + j edge cost)
Once you have your table filled in, start at bottom right corner. Starting from your goal, Choose to go to the node with the lowest cost of getting there. Work your way backwards choosing the lowest value until you reach the start node (or rather the array entry corresponding to the start node). This should give you the optimal path very simply.
Dynamic programming works by solving the optimization on smaller sub-problems. In this case the sub-problems are optimal paths to preceding nodes. I think the rectangular nature of your graph makes this a good fit.

How to start Edmonds-Karp implementation if all the paths have same lengths?

How can I select the starting path for the Edmonds-Karp algorithm if all the paths are the same length? In this case, maximum flow changes according to path sequence decision.
I think there is a problem with how you handle capacities at the vertices. The usual way this is done is by splitting the vertex v in two vertices v' and v'' and adding an edge between v' and v'' with the capacity of the vertex. All edges connected to v(i.e. for which v is destination) should be connected with v' in the new graph and all edges from v should start from v'' in the new graph.
You probably know that when you let flow x-a-b-y 3 you add to the capacity of the reverse edges. In that case you will add the edges a x 3, b a 3, y b 3. If you do the graph representation as I described you will see that there is additional flow you can use in the first case(I think it can pass through x-a-d-c-b-y, but have not checked it).
The selection of the shortest path should not change the answer - as I mentioned in my comment we only select the shortest path on each step to avoid bad cases where the performance suffers, but the answer is always the same.
Hope this answer helps.

How to find closed loops in graph networks

I have an undirected graph network made of streets and crossings, and I would like to know if there is any algorithm to help me finding closed loops, ie places where I can put buildings.
Any help appreciated, thanks !
Based on comments to my earlier answer:
It seems the graphs are all undirected and planar, i.e. can be embedded in a 2D plane without crossing edges, and one such embedding is given. This embedding will partition the plane. E.g. a figure 8 partitions the plane in three: two "inner" areas and an infinite outer area. An alternative view is that all edges of a node are cyclically ordered. (This is the essential part that allows us to apply graph theory)
A partition is necessarily enclosed by a cycle, but not all cycles may partition a single area. In the trivial case of a figure 8, though, all three areas are directly associated with a distinct cycle.
The input graph can generally be simplified. Some nodes may have only a single edge; they can't contribute to the partitioning and can be removed along with the edge. Other nodes have two edges connecting distinct nodes. Here, the node and the two edges can be replaced by a direct edge connecting the neighbors. I.e. a figure 8 graph can be simplified to two nodes and three edges between them. (This is not a necessary step but helps computation).
Now, each vertex will have two areas to either side (since they're undirected, "left and right" aren't obvious distinctions). So, for |V| vertices, we need to consider 2 * |V| sides. They're in general not distinct. Two adjacent edges (connected to the same node) may border the same area, if they're also adjacent in the cyclic order of edges of that node. Obviously, for nodes with only two edges, the two edges share both areas (which is why we'd eliminated them in the previous step). For nodes with three edges, any two edges share at least one area.
So, here's how to enumerate those areas: Assign a sequential number to all edges and vertices. Assign a direction to each edge so it runs from the lower-numbered edge to the higher. Start with vertex 1, right side, and number this area 1. Trace the boundary edges of this area, assigning the same number 1 to the appropriate sides of its boundary edges. You do this by taking at each node the next adjacent edge in counter-cyclical order. When you get back to your starting point, you know all edges bounding area 1.
You then check the left edge of the first vertex. If it's not part of area 1, then it's area 2, and you apply the same algorithm. Next, check vertex 2, right side and left side, etc. Each time you find an edge and a side that's unnumbered yet, assign the next area number and trace the edges of the newly founded area.
There's a slight problem with determining which area number corresponds to infinity. To see this, take a simple () graph: two edges, two nodes, and two areas (inside and outside). Due to the random numbering of edges and vertices, outside may end up as either 1 or 2. That's unavoidable; in graph theory there's no distinction between inside and outside.
It's a standard function in the Boost Graph library. See this previous answer for details.