I have a graph where each node is an 3D point and the edges represents the distances between those points in 3D space. The graph is not fully connected. This means between point A and B, there may be a single direct way to go or multi stage way (e.g. A->C->D->E->B).
I want to find the shortest closed path that passes through a given set of Points (all of points should lay on the path).
Is there a ready implementation for that in Boost Graph library?
P.S. The path should start and end from the same vertex (Cycle)
This is the Traveling Salesmen Problem, which is NP-hard.
There's one approximation algorithm of optimal solutions in BGL: https://www.boost.org/doc/libs/1_71_0/libs/graph/doc/metric_tsp_approx.html
It assumes that the the distances have some metric properties:
A very natural restriction of the TSP is to require that the distances between cities form a metric to satisfy the triangle inequality; that is the direct connection from A to B is never farther than the route via intermediate C:
This suits your problem because your graph models points in 3D space
Related
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.
I did some research about A* algorithm and other graph-based algorithm but most of the tutorials and implementations are made with a 2D-grid and with 2 parameters (x,y coordinates).
Does someone has good tutorials with examples (C++ or Java) or links about A* in different configuration space. Such as 3D environment or non-grid, with x,y,z coordinates or x,y, orientation, or anything else...
Thanks
The general A* algorithm does not include a grid nor a dimension. It is a shortest-path algorithm for a weighted graph. What the nodes and edges of this graph are, is completely scenario-specific.
In the case of a 2D-grid, the nodes are the grid cells and edges specify adjacency. A similar graph can be built from a 3D grid. If you don't want to restrict yourself to grids, you can built any graph with an arbitrary connectivity.
Nodes do not necessarily need to correspond to positions and weights do not necessarily need to correspond to distances. For example, the Pinocchio System uses A* to grow a skeleton embedding. The distance here is the embedding quality / energy (although the energy is not accumulated along a path). Nodes correspond to partial embeddings.
I was reading through the BOOST library and noticed that they dint have an algorithm to find bridges in a graph, they do have one to find articulation points. Is there anyway this could be done efficiently?
I have an idea:
1. Use the BOOST to find articulation points
2. Using out_edges,find all edges attached the each articulation point
3. remove them and calculate the number on connected components,( I assume my graph is originally fully connected), if its more than 1,i add this edge to the bridges.
QUESTION: Is it necessary for bridges to be attached to articulation points? I just assumed they are,couldn't find anything no the net.
I would also like an idea how to approach this.
My other approach would be more naive and take O(v*(V+E)), which is very bad.
Sounds a bit slow with the whole graph rewriting. You'd have to check if Boost counts a single-connected vertex as an articulation point. (If not, this slightly complicates things).
Now it is fairly obvious that a bridge must be an edge between two articulation points, but not all edges between articulation points are necessarily bridges. Consider a chain of 4 articulation points connected by 3 edges: A-b-c-D. Now add a node e connected to both b and c. The outer two bridges remain bridges, and so all 4 original nodes remain articulation points, but the middle node is no longer a bridge.
This means we have a necessary but insufficient extra condition: both nodes of the edge must be articulation points. Here's where the slight complication steps in; if Boost doesn't count single-connected nodes as articulation points, you have to treat them specially. But that's still simple; that one edge is necessarily a bridge.
This extra condition is quite efficient in dense graphs, as most nodes will not be articulation points. As a result, you cull most candidate edges before trying to alter the graph. Secondly, you don't need to test the component count of the resulting altered graph. You just need to check if the two articulation points are still connected after you cut the edge linking them directly.
There is a much easier way when you realize if a biconnected component only contains one edge this edge is a bridge. It is very easy to implement using boost (http://www.boost.org/doc/libs/1_58_0/libs/graph/example/biconnected_components.cpp):
Calculate the biconnected components
Create a edge counter for each component. Iteratate over all edge and increase the coresponding edge counter of the respective component
Iterate again over all edges and check if the edge counter of the corresponding component is 1, if so this edge is a bridge
Suppose I've some points on a mesh (2+) that can be anywhere on the mesh, suppose for example these (ignore the small points, just consider the sphere):
http://i.stack.imgur.com/nDzW3.png
(sorry can't put directly the image)
But note that they can be everywhere
How can I get a closed ring of points that goes around the mesh and include the given points?
I have access to both neighbours and neighbouring faces for each point on the mesh.
Any idea?
I suppose that ring goes on existing mesh edges. Than mesh edges can be seen as a graph and problem is similar to Travelling salesman problem on given vertices.
TSP is hard (slow) to solve. I suppose that points positions approximate circle, than it is probably enough to use simpler algorithm. Start from one point and find closest of input points (Dijkstra's). Than start from that point and find closest of not visited points. Repeat that until path returns to starting point.
I am currently working on a project that has a vector containing X and Y coordinates for approximately 800 points. These points represent an electric network of lines.
My goal is to compute the shortest distance Path between a Point A and Point B that can be or can not be located along the path given by the vectors containing the X-Y coordinates of the electric lines.
I have read about the Dijkstra Algorithm but since i am not that much familiar with it, I am not sure if I should go in that direction. I will be very thankful if I can get any feedback or comments from you that can direct me to solve this matter.
Any pathfinding algorithm depends on paths, points are just meaningless. What you have now is a list of "waypoints". However you have not explained how those points connect. For example if any and every point is connected to each other point the shortest distance would simply be the pythagoral distance between A & B. - I'm also unsure what you mean by X-Y coordinates of electric lines, such a "line" would always have a start & end position?
So the first step is to add to each point not only the x,y coordinates, but also a list of connectable points.
Once you did this you can start using a pathfinding algorithm (In this case A* would seem better than Dijkstra's though). It would simply be a standard implementation with each "cost" the actual distance between a point. (And for A* the heuristic would be the pythagoral distance to the end point).
For a good tutorial about A* (and other algorithms) you should check Amit's pages
EDIT, in reply to the comments.
It seems the first step is to convert a set of line segments to "points". The way I would go through this is:
collection AllPoints {containing Location & LinksToOtherPoints}
for each Segment
get start/end Point of Segment
if Point.Location is not in allPoints
add Point to AllPoints
add the other Point of Segment to LinksToOtherPoints
You then have simply a list with all points & the connections between them. As you have to constantly search the allPoints collection I suggest storing that in a binary tree structure (sets?).
For computing the shortest path Dijakstra would be fine.
You may get faster results from using A*, which uses a best guess of the distance in order to focus its search in the right direction, thereby getting there quicker.
If you are repeatedly querying the same data set, then memoization is fine.
Those people who recommend a brute-force algorithm are fools - it's worth taking a little time to learn how to program an efficient solution. But you could calculate the shortest path between all points using the Floyd-Warshall algorithm. Unfortunately, this won't tell you what the shortest path is just how long it is.
Just calculate the distance for all possible paths and pick the shortest one.
800 paths is nothing for modern PC. You will not even notice it.