The problem is this:
I have a graph G=(V,E). a subgroup of vertices U<=V, and a start vertex s. weight function w for the edges.
I need to find the shortest path from 's' that passes through all vertices in U.
The calculation can be approximated, there should be some balance between calculation time and path length.
I need a fast algorithm/heuristic that will produce a fine approximation for the shortest path.
This algorithm shouldn't be too complicated to implement (in C++). for example, I have already thought of a way to make this into a Traveling Salesman Problem, and to use a TSP solver library or something that uses some kind of heuristic, but couldn't find any, and implementing the heuristic myself will be too hard.
Thanks advanced! =]
This is a variant of the Travelling Salesman Problem called the Set TSP problem, or Generalized TSP. Here's the Wikipedia link.
The reference from the above article link to a method for converting a Generalized TSP problem to a TSP problem without doubling the number of nodes in the graph.
The record-holding TSP solver is freely available and is known as Concorde, and can be downloaded from here, it can be run as a command-line tool (possibly as a library, not sure).
I came across GTSP when trying to create a solver for the game RevolvoMan4k by getting all pieces of money on each level with the minimum number of button pushes. (it's a fun game, but after level 50, the levels are random, so some may be impossible and need to be skipped with 'N').
Imagine that you have 3 vertices: S, A and B.
Now, let's say we need to find the shortest path from S through A and B. The easiest way to do this, is to find which point is closer to S: A or B. If your graph actually has some spatial data, you can approximate this using the vertices's co-ordinates, otherwise, you'll have to get the shortest path from S to each of your destinations. Pick the closest destination, in this case let's say that's A, and travel there. Now the only place you have left to go is B. Calculate the shortest path from A to B, and go there.
Now, in a situation with more than 2 destinations, you could do this recursively. I don't know C++, but here's some pseudocode that could get you started
function pathThrough(startNode,destinationNodes[])
closestNode = getClosestNode(startNode,destinationNodes)
newDestinations = removeFromArray(destinationNodes,closestNode)
return joinPaths(getShortestPath(startNode,closestNode),pathThrough(closestNode,newDestinations.))
for the closestNode and getShortestPath functions, you can use whatever search algorithm suits your graph, A*, dijkstra's algorithm,...
Related
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
Is it possible to easily solve the TSP using the boost::metric_tsp_approx function?
In it's current form metric_tsp_approx solves the following problem which is to find some approximately optimal path through a set of points, touching each point once.
the solution might be
However I have a more interesting variant I wish to solve
Above I have a series of segments in the plane. The segments need to be connected using a TSP solution but the connection is only allowed to enter on the green side and exit on the red side. For example a solution might be
where the yellow lines are solution. Is it possible to construct such a problem that boost::graph or metric_tsp_approx can solve it?
I think I'd treat the segments as nodes. No need to bother which side is entry/exit: you can decorate your path later.
So, make a graph model that has the segments as vertices, find an approximately shortest path { Segment1, Segment..., SegmentN } using the current algo.
The path you are looking for can be expanded simply as:
{ entrypoint(Segment1), exitpoint(Segment1),
..., ...
entrypoint(SegmentN), exitpoint(SegmentN) }
I have a few ordered points (less than 10) in 2D coordinates system.
I have an agent moving in the system and I want to find the shortest path between those points following their order.
For background the agent can be given a position to go to with a thrust, and my objective is to plot the fastest course given the fact that the agent has a maximum thrust and maximum angular velocity.
After some research I realized that I may be looking for a curve fitting algorithm, but I don't know the underlying function since the points are randomly distributed in the coordinates system.
Please, help me find a solution to this problem.
I am open to any suggestion, my prefered programming language being C++.
I'm sure there is a pure mathematical solution such as spacecraft trajectory optimization for example, but here is how I would consider approaching it from a programming/annealing perspective.
Even though you need a continuous path, you might start the path search with discreet steps and a tolerance for getting close enough to each point as a start.
Assign a certain amount of time to each step and vary applied angular force and thrust at each step.
Calculate resulting angular momentum and position for the start of the next step.
Select the parameters for the next step either with a random search, or iterate through each to find the closest to the next target point (quantize the selection of angles and thrust to begin with). Repeat steps until you are close enough to the next target point. Then repeat to get to the next point.
Once you have a rough path you can start refining it (perhaps use the rough point from the previous run as target points in the new one) by reducing the time/size of the steps and tolerance to target points.
When evaluating the parameters' fitness at each step you might want to consider that once you reach a target point you also want to perhaps have momentum in the direction of the next point. This should be an emergent property if multiple paths are considered and the fitness function considers shortest total time.
c++ could help here if you use the std::priority_queue and std::map for example to keep track of the potential paths.
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.
I want to find path in 2d platform game, teeworlds. The player there can move left/right, jump, and use hook, that lets you move upward the wall or move under ceiling. Well, its hard becouse normal pathfinds like a* or bfs cant exist here, cuz you cant just move up. I need to find path btw 2 players so 1 can go to the second one. There are 3 types of tiles, collide, nohook (you cant hook it) and nothing (air). I have the map in format int map[w][h] where 0=air, 1=collide, 2=nohook. map isnt modified for whole game time.
I have completly no idea how to do that. If you can help me, I'd be pleased.
PS. The question is general about platform games, teeworlds is only one of them...
From the pathfinding algorithm's standpoint you could treat the climbable walls as if they were normal walkways, so the algorithm does not stop there.
I don't think I completely understand the possibilities in your game. But this is how it works in general:
Path finding algorithms work on graphs (directed, undirected, with costs or equal costs for all edges doesn't matter). All you have to do is model your graph according to your game's rules. I.e. if there is only a normal way between field i and j than cost(i,j) = normal, if there is an additional way to use a hook, it could would be that cost(i,j) = min(hook, normal) . and so on. Once you have a graph (i assume it has to be directed for your game) all the normal Pathfinding algorithms will work.
if there are requirements like "you can only use hook n-times", a multi-label dijsktra can work.
pathfinding algorithms work on graphs in general
movement from one cell to another means that there is a connection between two cells (for instance in four directions). But you can also link to some other cell (the ceiling).
A* as a general search algorithm can still be applicable here, you just need to find a way to represent your platform game path-finding problem as a general search problem. So while you might have been introduced to A* as an algorithm to find a path through a grid-like maze, that is just a specific case of such a general search problem.
The more general case being graphs, where edges represent moves or actions and nodes represent positions or states.
One way to use A* for the game you mention is by taking an example from this Infinite Mario AI. This implementation of A* works locally and is rerun every tick to get the most optimal actions at that exact moment which is great for a fast-paced game like Mario or the game you mention, but be mindful that this is different from A* when it's used to solve a maze, in which case the path is found only once and it is like a global plan to be followed until its end.
Use simple BFS method, preprocessing the pairs to nodes.