Given a square grid (undirected graph), is there any way to find a path which will visit as much as possible vertices.
each vertex can be visit only once. It means that the path will be Hamilton tour if exist, or be a longest path.
The graph has some walls. Wall is a vertex has no edge connect to neighbors.
I has a solution (in mind), but it's very similar to find all path and chose the first one has most vertices visited.
Find a path will visit all neighbors from given start vertex to the end (no way can go).
look back to the current path until the starting vertex, if there is any vertex has neighbors outside of the current path, process like
step 1 from the found vertex and its new neighbors.
analysis and choose the longest path (has most vertices).
I found similar problem, cannot understand what does #Juho mean:
Choose a successor si to top(S), and try to find a path si−1⇝si avoiding vertices in F. If a path is found, insert the vertices on the path si−1⇝si to F.
I don't have enough reputation to add a comment there.
my solution get performance trouble, I guess. Any suggestion?
This is more of a Hamiltonian Path problem. It's NP-complete so you'll need to do an exhaustive search. Get your brute-force on. I can only suggest that it is possible to use threading to alleviate your performance problem; divide up your starting vertices evenly amongst your available threads. Terminate in the event that you find a Hamiltonian Path, else the longest path wins.
The algorithm itself is just going to have to find all possible paths. I there is possibly a heuristic to stop bothering with a path that seems to be getting bad results but that will mean the solution may not always be correct.
Related
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 school assigment to create a program which gets a graph and finds out mininal spanning tree with condition that path between two points (which are preselected on run start) will be shortest by NUMBER OF EDGES between them.
The task itself is OK but where I struggle is optimization. When I find my path between A and B (preselected points) I try to recursively find all other possible options by DFS and then do MSTs and choose the smallest. Since the path must be of lowest number of edges and I found one of those paths by first BFS I know that I can cut of my DFS search after X recursions where X is number of edges between A in B found in the BFS. It works very fast in certain types of graphs (where number of edges is to 3 times number of vertexes) but when edges are for example 10 times bigger it just runs without stopping.
I asked my friend for a hint and he said me he uses BFS for recursively finding the other paths, and he is okay, but what is the performance difference? DFS will try first to run down and stops when reach the certain point or wastes hops avaiable, BFS goes wide first and then ends all paths at the same depth step but still I do same ammount of hopping right?
What am I missing here? Or did I understand him wrong? Thanks for any ideas.
EDIT: I tried to check which edges I already visited in the particular DFS run to avoid going opposite direction, back to the point where i was and so on but it only generated delay on certain group of graphs while not helping noticably with others.
EDIT2: swapped edge and vertex quantity (cant be more vertexes than edges)
So I finished my assigment and when looking for other paths/all paths between two points A/B, DFS and BFS gets the same result as far as I found out.
The key for me was right optimization of solution. My final solution combines going wide with going deep and works like this (maybe it can be done faster but I doubt it):
We know the length (in number of edges) between points A/B (we
ran BFS once to find out path).
We run something like BFS from
end point B and in every vertex we make mark how much hops we did
from the end and call this again on all outgoing edges (we stop when
hops == lengthOfPath(A,B)).
Then we do DFS from source point A
and combine all vertexes which hold proper hop value into the path
by recursion.
In other words we mark all point by their reachability from B and then from A we go over those accessible (with set value other than default and with proper value of hops from A) and combine all possible paths together.
There are our paths. (I left this vague intentionally because task is still active). If anyone would need better explanation in future, post comment and I will elaborate. If someone finds better solution, post it as your answer and if right I will tick it as right answer.
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 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 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.