This is just something I came up with on my own, but it seems like a fun problem and it has me stumped.
You have a set of points in two-dimensional space, with one point designated "Start" and one "End". Each point has coordinates (in meters from the origin), but also an "acceleration number" (in meters/second of delta-V). Upon reaching a point (including the start), you may accelerate by up to that point's acceleration number in any direction. Edge cost is dependent on your current speed, but you also have to be moving in the correct direction.
Is there an efficient algorithm for finding the fastest path through to the end point? I haven't come up with anything better than "Try every path and check results". Djikstra's and other simple algorithms don't work, because you can't easily say that one path to an intermediate point is better or worse than another, if they have you arriving with different initial velocities.
If that's too easy, what if you add the requirement that you have to stop at the end point? (i.e., you must have less than its acceleration value when you reach the end.)
EDIT: To be clear, direction matters. You maintain a velocity vector as you traverse the graph, and acceleration means adding a vector to it, whose magnitude is capped at that point's acceleration number. This means there are situations where building up a huge velocity is detrimental, as you will be going too fast to "steer" towards other valuable points/your destination.
I think that the requirement that you only use the acceleration from each point once makes this problem NP complete in the general case. Consider an input that looks like this:
If the "huge distance" between the end point and the rest of the points is large enough to dominate the cost of the final solution, finding an optimal solution will boil down to finding a way to pick up as many speed boosts as possible from the start of the graph. If you only allow each point to be passed once, this would be equivalent to to the Hamiltonian path problem, which is NP complete.
That said, your problem has some extra rules on top of it (the distances are euclidean, the graph is always complete) which might end up making the problem easier.
You can try solving this problem backwards by recursively tracing paths from the end to each other node, then designate maximum speed along the line to be able to turn from that node to any other. The culling rule will be if a path from current to next node exists with less velocity and less time spent from end, which will mean that the other path is more optimal by default because it can reach more nodes and takes less time. Once a path reaches start node, it should get recalculated based on the maximum speed achievable at the start and stored. Then you gather the path with less time spent.
You have to search for any available path here, because the available paths on your graph are dependent on past state with an indirect mechanics, using less speed allows more choices.
Related
I asked this question three days ago and I got burned by contributors because I didn't include enough information. I am sorry about that.
I have a 2D matrix and each array position relates to the depth of water in a channel, I was hoping to apply Dijkstra's or a similar "least cost path" algorithm to find out the least amount of concrete needed to build a bridge across the water.
It took some time to format the data into a clean version so I've learned some rudimentary Matlab skills doing that. I have removed most of the land so that now the shoreline is standardised to a certain value, my plan is to use a loop to move through each "pixel" on the "west" shore and run a least cost algorithm against it to the closest "east" shore and move through the entire mesh ultimately finding the least cost one.
This is my problem, fitting the data to any of the algorithms. Unfortunately I get overwhelmed by options and different formats because the other examples are for other use cases.
My other consideration is that when the shortest cost path is calculated that it will be a jagged line which would not be suitable for a bridge so I need to constrain the bend radius in the path if at all possible and I don't know how to go about doing that.
A picture of the channel:
Any advice in an approach method would be great, I just need to know if someone knows a method that should work, then I will spend the time learning how to fit the data.
You can apply Dijkstra to your problem in this way:
the two "dry" regions you want to connect correspond to matrix entries with value 0; the other cells have a positive value designating the depth (or the cost of filling this place with concrete)
your edges are the connections of neighbouring cells in your matrix. (It can be a 4- or 8-neighbourhood.) The weight of the edge is the arithmetic mean of the values of the connected cells.
then you apply the Dijkstra algorithm with a starting point in one "dry" region and an end point in the other "dry" region.
The cheapest path will connect two cells of value 0 and its weight will correspond to sum of costs of cells visited. (One half of each cell weight is coming from the edge going to the cell, the other half from the edge leaving the cell.)
This way you will get a possibly rather crooked path leading over the water, which may be a helpful hint for where to build a cheap bridge.
You can speed up the calculation by using the A*-algorithm. Therefore one needs a lower bound of the remaining costs for reaching the other side for each cell. Such a lower bound can be calculated by examining the "concentric rings" around a point as long as rings do not contain a 0-cell of the other side. The sum of the minimal cell values for each ring is then a lower bound of the remaining costs.
An alternative approach, which emphasizes the constraint that you require a non-jagged shape for your bridge, would be to use Monte-Carlo, simulated annealing or a genetic algorithm, where the initial "bridge" consisted a simple spline curve between two randomly chosen end points (one on each side of the chasm), plus a small number or randomly chosen intermediate points in the chasm. You would end up with a physically 'realistic' bridge and a reasonably optimized cost of concrete.
I'm dabbling in some path-finding systems (right now A*), but I'm no where near experienced enough to fully grasp the concepts behind everything. So please forgive me if this post is riddled with ignorance, or false assumptions.
My goal is to be able to have an object traverse multiple planes to reach a destination, with variable entrances to each level, and each level having different designs.
imagine a cave system that has 8 entrances on top, and your goal is to reach 6 layers down... Some of the caves link up, and therefor paths can be shared, but others are isolated until a certain point.... etc etc. Also, the inter connectivity of paths can be altered on each level.
I know there are some systems that can do this, but my goal is eventually best/fastest option, as well as the ability to do this calculation quickly (a possibility of at least 80+ different paths being calculated at any given time)
An example would be something like this:
Every 'layer' is another 'level', or plane. The green is a path that is both up and down between layers. during the course of the instance, paths can be placed anywhere, and any divisions inside a layer can be removed (but for the case of this instance, they are organized like that)
Its been fairly easy to implement A* for some basic path finding on a single level (eg, get from one position to a ladder going down). But trying to decide which ladder will lead to the ultimate goal is what is difficult.
My initial thoughts were to do something more like a data structure linking the paths to each other on the same level, and do some sort of tree traversal to decide which ladder the the path finding should direct you to when you reach a certain level...but that got complicated quickly, seeing as levels can be altered at any given point.
Like i said, I'm not certain how A* actually works, or the basics behind it... but its the basic algorithm that most people have said will work for multi-layered designs.
I know that it really depends on the engine, and the implementation of the algorithm, so I'm not asking for specifics... but rather some pointers on the best way to approach the situation;
Should I find a working A* implementation that has multi-level calculations built in, and change my level architecture to fit it?
Should I simply utilize a 2d A* implementation, and create a 'path' structure, to give the pathing instructions on each level?
Is there another approach to this style of design that would be more beneficial, and efficient (taking into account the number of calculations/paths to find)?
Thanks!
An approach that comes to mind:
For each level, calculate all the Manhattan distances (perhaps /2 if you can move diagonally) (that's assuming each level is a 2D grid) from each ladder going up to each ladder going down, and let each floor's value be the shortest distance of those.
Now we can simply let the A* heuristic be the sum of distances from the current floor to the bottom.
To prevent repeated computation of paths on each level, we can precompute each possible path from ladder to ladder on every level - we can also then use the shortest of these paths rather than the Manhattan distances for the heuristic.
You say there is a possibility of at least 80+ different paths being calculated at any given time.
If these are all on the same map, you should consider, for each ladder, calculating what the next ladder we should go to is which will lead to the shortest path (and also its cost) (possibly using some derivative of Dijkstra's algorithm starting from the bottom), then we can simply, from any starting point, check the distances to all ladders on the same floor and the cost of their shortest path, and simply pick the one giving the lowest sum of distance and shortest path.
We could even extend this by storing, for any given point, what the next square is one should move to for the shortest path.
If the map changes a lot, storing the next point for any given point is probably not viable, but don't discount storing the next ladder for each ladder.
What is the difference between maximal flow and maximum flow. I am reading these terms while working on Ford Fulkerson algorithms and they are quite confusing. I tried on internet, but couldn't get a reasonable answer. I believe maximum flow is quite clear as it means maximum amount of flow that can be transferred from source to sink in a network, but what exactly is maximal flow.
Please answer in layman terms if possible.
Thanks.
Short answer:
Think about the top of the mountains,
each of them is a maximal solution,
there is not place nearby that is higher than them,
but only the top of the Everest mountain has the maximum height and
is therefore the maximum solution.
Longer answer:
Let me explain it in geometric terms:
think about a plane (e.g. a large peace of paper).
Each point on the plane is a possible solution for the problem.
The height of each point is the quality of the solution corresponding to that point.
In optimization we want to find the optimal solution, i.e. the highest point on the plane.
One idea to find the optimal solution is to start from a possible solution in the plane and
improve it little by little:
each time we move from a point to one near it which is higher.
This is called a local search algorithm.
This process stops when we reach a point which is higher than all points near it.
Such a point is called a local optimum.
The corresponding solution is called maximal as we cannot increase the quality of the solution by moving to any solution near it.
However, a maximal solution doesn't need to be the optimal solution,
it is optimal in comparison to its neighbors.
There are common conditions which if satisfied
we will not have local optimals on the plane which are not globally optimals.
In such situations we can use local search algorithms to find the optimal solution.
One such condition is if the plane of solutions is convex,
intuitively for every two points we have all points on the line connection them
also in the solution space and
the quality of each of them can be determined from
the relative distance of the point to the two endpoints and
the quality of the two endpoints.
Optimization over convex spaces is studied in convex optimization.
Now, lets go back to the max flow problem.
Fix a graph as input.
Think of each flow that satisfies the capacity and preservation of flow
requirements as a point.
We call these valid flows.
We want to find a maximum flow.
Two points are near each other if we can obtain one by increasing or decreasing
the flow through a path from the source to the sink.
We can start by the flow where the flow on all edges are zero
(this is a valid flow).
At each step we find a path from the source to the sink in the updated remaining capacity graph (the weight of each edge is the amount of its capacity that is not being used)
somehow (e.g. using BFS) and increase the flow by adding this.
This gives us a local search algorithm.
The problem is that the space of solutions is not convex and
we may end up with a flow
that we cannot increase any more but it is not a maximum flow.
What can we do?
One idea is to change the space of solutions to a convex one.
For intuition think about a star on a plane.
The points inside the star do not make a convex space
but we can turn it into a convex space by including more points in our solution space
and turning it into a pentagon.
This is essentially what we do by consider the existing flow on
the original edges of the graph
as new edges (called residual edges)
where flow over them corresponds to decreasing the existing flow on the original edges.
This makes the space convex and our local search algorithm does not get stuck on solutions
which are locally optimal but not globally optimal.
I need to find the optimal path connecting two planar points. I'm given a function that determines the maximal advance velocity, which depends on both the location and the time.
My solution is based on Dijkstra algorithm. At first I cover the plane by a 2D lattice, considering only discrete points. Points are connected to their neighbors up to specified order, to get sufficient direction resolution. Then I find the best path by (sort of) Dijkstra algorithm. Next I improve the resolution/quality of the found path. I increase the lattice density and neighbor connectivity order, together with restricting the search only to the points close enough to the already-found path. This may be repeated until the needed resolution is achieved.
This works generally well, but nevertheless I'd like to improve the overall algorithm performance. I've implemented several tricks, such as variable lattice density and neighbor connectivity order, based on "smoothness" of the price function. However I believe there's a potential to improve Dijkstra algorithm itself (applicable to my specific graph), which I couldn't fully realize yet.
First let's agree on the terminology. I split all the lattice points into 3 categories:
cold - points that have not been reached by the algorithm.
warm - points that are reached, but not fully processed yet (i.e. have potential for improvement)
stable - points that are fully processed.
At each step Dijkstra algorithm picks the "cheapest" warm lattice point, and then tries to improve the price of its neighbors. Because of the nature of my graph, I get a kind of a cloud of stable points, surrounded by a thin layer of warm points. At each step a warm point at the cloud perimeter is processed, then it's added to the stable cloud, and the warm perimeter is (potentially) expanded.
The problem is that warm points that are consequently processed by the algorithm are usually spatially (hence - topologically) unrelated. A typical warm perimeter consists of hundreds of thousands of points. At each step the next warm point to process is pseudo-randomal (spatially), hence there's virtually no chance that two related points are processed one after another.
This indeed creates a problem with CPU cache utilization. At each step the CPU deals with pseudo-random memory location. Since there's a large amount of warm points - all the relevant data may not fit the CPU cache (it's order of tens to hundreds of MB).
Well, this is indeed the implication of the Dijkstra algorithm. The whole idea is explicitly to pick the cheapest warm point, regardless to other properties.
However intuitively it's obvious that points on one side of a big cloud perimeter don't make any sense to the points on another side (in our specific case), and there's no problem to swap their processing order.
Hence I though about ways of "adjusting" the warm points processing order, yet without compromising the algorithm in general. I thought about several ideas, such as diving the plane into blocks, and partially solving them independently until some criteria is met, meaning their solution may be interfered. Or alternatively ignore the interference, and potentially allow the "re-solving" (i.e. transition from stable back to warm).
However so far I could not find rigorous method.
Are there any ideas how to do this? Perhaps it's a know problem, with existing research and (hopefully) solutions?
Thanks in advance. And sorry for the long question.
What you're describing is the motivation behind the A* search algorithm, a modification of Dijkstra's algorithm that can dramatically improve the runtime by guiding the search in a direction that is likely to pick points that keep getting closer and closer to the destination. A* never does any more work than a naive Dijkstra's implementation, and typically tends to expand out nodes that are clustered on the frontier of the warm nodes that are closest to the destination node.
Internally, A* works by augmenting Dijkstra's algorithm with a heuristic function that estimates the remaining distance to the target node. This means that if you get can get a rough approximation of how far away a given node is from the destination, you can end up ignoring nodes that don't need to be processed in favor of nodes that are likely to be better.
A* was not designed as a cache-optimal algorithm, but I believe that the increase in speed due to
Expanding fewer nodes (less in the cache), and
Expanding nodes closer to the goal (which were processed more recently and thus more likely to be in the cache)
will give you a huge performance increase and better cache performance.
Hope this helps!
I'm facing a hard problem:
Imagine I have a map of an entire country, represented by a huge matrix of Cells. Each cell represents a 1 square meter of territory. Each Cell is represented as a double value between 0 and 1 that represents the cost of traversing the cell.
The map obviously is not fittable in memory.
I am trying to wrap my mind arround a way to calculate the optimal path for a robot, from a start point to a end position. The first idea I had was to make a TCP-like moving window, with a minimap of the real map arround the moving robot, and executing the A* algorithm inside there, but I'm facing some problems with maps with huge walls, bad pathfinding, etc...
I am searching the literature about A*-like algorithms and I could not visualize an approximation of what would be a good solution for this problem.
I'm wondering if someone has faced a similar problem or can help with a idea of a possible solution!
Thanks in advance :)
Since I do not know exact data, here's some information that could be useful:
A partial path of a shortest path is itself a shortest path. I.e. you might split up your matrix into submatrices and find (all) shortest paths in there. Note that you do not have to store all results: You e.g. can save memory by not saving a complete path but just the information: Path goes from A to B. The intermediate nodes might be computed later again or stored in a file for later. You might even be able to precompute some shortest paths for certain areas.
Another approach is that you might be able to compress your matrix in some way. I.e. if you have large areas consisting only of one and the same number, it might be good to store just that number and the dimensions of that area.
Another approach (in connection to precompute some shortest paths) is to generate different levels of detail of your map. Considering a map of the USA, this might look the following: The coarsest level of detail contains just the cities New York, Los Angeles, Chicago, Dallas, Philadelphia, Houston und Phoenix. The finer the levels get, the more cities they contain, but - on the other hand - the smaller area of your whole map is shown by them.
Does your problem have any special structure, e.g., does the triangle inequality hold/can you guarantee that the shortest path doesn't jog back and forth? Do you want to perform the query many times? (If so you can do pre-processing that will amortize over multiple queries.) Do you need the exact minimum solution, or will something within an epsilon factor be OK?
One thought was that you can coarsen the matrix - form 100 meter by 100 meter squares, and determine the shortest path distances through the 100 \times 100 squares. Now this will fit in memory (about 1 Gigabyte), you can run Dijkstra, and then expand each step through the 100 \times 100 square.
Also, have you tried running a forward-backward version of Dijkstra's algorithm? I.e., expand from the source and search forthe sink at the same time, and stop when there's an intersection.
Incidentally, why do you need such a fine level of granularity?
Here are some ideas that may work
You can model your path as a piecewise linear curve. If you have 31 line segments then your curve is fully described by 60 numbers. Each of the possible curves have a cost, so the cost is a function on the following form
cost(x1, x2, x3 ..... x60)
Now your problem is to find the global optimum of a function of 60 variables. You can use standard methods to do this. One idea is to use genetic algorithms. Another idea is to use a monte carlo method such as parallel tempering
http://en.wikipedia.org/wiki/Parallel_tempering
Whenever you have a promising path then you can use it as a starting point to find a local minimum of the cost function. Maybe you can use some interpolation to make your cost function is differentiable. Then you can use Newtons method (or rather BFGS) to find local mimima of the cost function.
http://en.wikipedia.org/wiki/Local_minimum
http://en.wikipedia.org/wiki/BFGS
Your problem is somewhat similar to the problem of finding reaction paths in chemical systems. Maybe you can find some inspiration in the book "Energy Landscapes" by Davis Wales.
But I also have some questions:
Is it necessary for you to find the optimal path, or are you just looking for an path that is OK?
How much computer power and time do you have at hand?
Can the robot make sharp turns, or do you need extra physics modelling to improve the cost function?