Adding waypoints to A* graph search - algorithm

I have the ability to calculate the best route between a start and end point using A*. Right now, I am including waypoints between my start and end points by applying A* to the pairs in all permutations of my points.
Example:
I want to get from point 1 to point 4. Additionally, I want to pass through points 2 and 3.
I calculate the permutations of (1, 2, 3, 4):
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 2 3
4 1 3 2
4 2 1 3
4 2 3 1
4 3 1 2
4 3 2 1
Then, for each permutation, I calculate the A* route from the first to the second, then append it to the route from the second to the third, then the third to the fourth.
When I have this calculated for each permutation, I sort the routes by distance and return the shortest.
Obviously, this works but involves a lot of calculation and totally collapses when I have 6 waypoints (permutations of 8 items is 40320 :-))
Is there a better way to do this?

First of all, you should store all intermediate calculations. Once you calculated the route from 1 to 2, you should never recalculate it again, just look up in a table.
Second, if your graph is undirected, a route from 2 to 1 has exactly the same distance as a route from 1 to 2, so you should not recalculate it either.
And finally, in any case you will have an algorithm that is exponential to the number of points you need to pass. This is very similar to the traveling salesman problem, and it will be exactly this problem if you include all available points. The problem is NP-complete, i.e. it has complexity, exponential to the number of waypoints.
So if you have a lot of points that you must pass, exponential collapse is inevitable.

As a previous answer mentioned, this problem is the NP-complete Traveling Salesperson Problem.
There is a better method than the one you use. The state-of-the-art TSP solver is due to Georgia Tech's Concorde solver. If you can't simply use their freely available program in your own or use their API, I can describe the basic techniques they use.
To solve the TSP, they start with a greedy heuristic called the Lin-Kernighan heuristic to generate an upper bound. Then they use branch-and-cut on a mixed integer programming formulation of the TSP. This means they write a series of linear and integer constraints which, when solved, gives you the optimal path of the TSP. Their inner loop calls a linear programming solver such as Qsopt or Cplex to get a lower bound.
As I mentioned, this is the state-of-the-art so if you're looking for a better way to solve the TSP than what you're doing, here is the best. They can handle over 10,000 cities in a few seconds, especially on the symmmetric, planar TSP (which I suspect is the variant you're working on).
If the number of waypoints you need to eventually handle is small, say on the order of 10 to 15, then you may be able to do a branch-and-bound search using the minimum spanning tree heuristic. This is a textbook exercise in many introductory AI courses. More waypoints than that you will probably outlive the actual running time of the algorithm, and you will have to use Concorde instead.

Related

Issue with min cost path

I was solving min cost path problem through dynamic approach but suddenly I realised that greedy approach is also working.
I applied greedy like this :
choose the min of bottom, right and diagonal cost and move in the min cost path.
1 2 3
4 8 2
1 5 3
where numbers are cost which will be added to the required cost if we include that point.
path from 1 to 3 is 12 through greedy is 8.
If my approach doesn't follow all examples, the what is that example?
How about a map such as:
1 1 1
2 10 10
1 1 1
Your greedy approach will end up taking 1+1+1+10+1, instead of 1+2+1+1
Greedy algorithms can be 'beaten' by giving them a long meandering path with several small steps:
2 2 e
2 ∞ 0
s 3 0
In this case, going from s to e will require either
The greedy solution: See that 2 is smaller and slog through several three 2's for a total cost of 6
A dynamic solution: See that after the three there is an easy path for a total cost of 3.
Also, I'd take a look at how your two algorithms define length. The optimal path is actually 1 -> 4 -> 2 -> 3 which has a cost of 10. If your dynamic solution isn't returning that, it may indicate that something else is going on.

Triangle max sum using depth first search

I have the classic problem with a triangle and need to get the max path. I am allowed to move from (i,j) to (i,j-1), (i, j+1), (i+1,j)
Example input:
1
1 2 3
1 2 3 4 5
1 2 3 4 5 6 7
and the maximum path is the sum of (1) + (2 + 3) + (4 + 3 + 2 + 1) + (2 + 3 + 4 + 5 + 6 + 7). I am not allowed to move on a node twice
I know how to solve this using DP but this problem has been shown to us at the Artificial Intelligence class and the solution it needs is using DFS/GBFS
How is it possible to solve this problem using DFS? Only recursive came to my mind but it's not near close to DFS.
I am representing the input as a graph, so for the following
1
2 3 4
5 6 7 8 9
I have the following graph
1 -> {3}, 3 -> {2, 4, 7}, 4 -> {3, 8} etc
I was thinking of doing a recursive function, MaxSum(node) and start from node 1 and do something like that
return Max(MaxSum(neighbour_1), MaxSum(neighbour_2), ..., MaxSum(neighbour_n)) + node
where each neighbour_i is unvisited neighbour
But where does the DFS part come in?
Also, how could I solve this problem using GBFS?
I am not interested in code or something, only algorithmic explanations
But where does the DFS part come in?
The graph you have is acyclic and the problem you are trying to solve is longest path problem (after transforming the node weights to edge weights). The general solution requires you to use DFS to find a topological order but in your case you know an easy topogical order, the one just like in your example:
1
2 3 4
5 6 7 8 9
You use this order for second part - the DP solution. So in a way, you are skipping the DFS part.
You could explicitly run DFS for the first path and it could give a different topological order (depending on how you traverse the edges) but it's just a waste of effort.
Also for the second part, instead of performing the DP you could use BFS level by level to update the neighbors of the elements in the current level. But again it doesn't make much sense since using DP would give you the same results and would even be cheaper.

What is a good individual representation for a closed path planning task using genetic algorithm?

There is a n*n grid and in one of the cells of the grid lies an agent A.
A can travel T number of cells.
Each cell in the grid has some weight and the path for A has to maximize that weight.
A also has to return to its starting position within its traveling range T.
What can be a good individual representation to represent the paths?
Methods I have tried:
Chromosome is a list of coordinates.
Chromosome is a list of directions. Each gene is a direction like up, down, up-right, etc. Path never breaks in the middle.
Problems with both methods is that crossing-over almost always generates invalid paths. Paths become broken in the middle. They don't form a closed path. I can't seem to figure out a good way to represent the individual solution and an appropriate crossing-over method. Please help.
First of all, I would say that this problem is a better fit for other approaches, such as maybe ant colony optimization, greedy approaches that give good enough solutions etc. GAs might not work so well for the exact reason you describe.
However, if you must use GAs, here are two possible models that might be worth investigating:
Severely punish invalid paths by giving invalid moves a cost of -infinity. For example, if your chromosome says go from a cell x to an unreachable cell y, consider the cost of y -infinity. This might be worth combining with a low probability of crossover happening, something like 5% maybe.
Don't do crossover, just do some form of more involved mutation of the offspring.
If you want to get even fancier, this is somewhat similar to the travelling salesman problem, which has a lot of research in relation to genetic algorithms:
http://www.lalena.com/AI/Tsp/
http://www.math.hmc.edu/seniorthesis/archives/2001/kbryant/kbryant-2001-thesis.pdf
You could encode the path as a reference list:
Assume these are your locations (1 2 3 4 5 6 7 8 9)
A subset route of (1 2 3 4 8) could be encoded (1 1 2 1 4).
Now take two parents
p1 = (1 1 2 1 | 4 1 3 1 1)
p2 = (5 1 5 5 | 5 3 3 2 1)
which will produce
o1 = (1 1 2 1 5 3 3 2 1)
o2 = (5 1 5 5 4 1 3 1 1)
which will be decoded into these location routes
o1 = 1 – 2 – 4 – 3 – 9 – 7 – 8 – 6 – 5
o2 = 5 – 1 – 7 – 8 – 6 – 2 – 9 – 3 – 4
This way, a crossover will always yield valid results (whether this representation will help you solving your problem better is a different question).
Some additional information can be found here.

Generate multiple sequences of numbers with unique values at each index

I have a row with numbers 1:n. I'm looking to add a second row also with the numbers 1:n but these should be in a random order while satisfying the following:
No positions have the same number in both rows
No combination of numbers occurs twice
For example, in the following
Row 1: 1 2 3 4 5 6 7 ...
Row 2: 3 6 15 8 13 12 7 ...
the number 7 occurs at the same position in both rows 1 and 2 (namely position 7; thereby not satisfying rule 1)
while in the following
Row 1: 1 2 3 4 5 6 7 ...
Row 2: 3 7 15 8 13 12 2 ...
the combination of 2+7 appears twice (in positions 2 and 7; thereby not satisfying rule 2).
It would perhaps be possible – but unnecessarily time-consuming – to do this by hand (at least up until a reasonable number), but there must be quite an elegant solution for this in MATLAB.
This problem is called a derangment of a permutation.
Use the function randperm, in order to find a random permutation of your data.
x = [1 2 3 4 5 6 7];
y = randperm(x);
Then, you can check that the sequence is legal. If not, do it again and again..
You have a probability of about 0.3 each time to succeed, which means that you need roughly 10/3 times to try until you find it.
Therefore you will find the answer really quickly.
Alternatively, you can use this algorithm to create a random derangment.
Edit
If you want to have only cycles of size > 2, this is a generalization of the problem.
In it is written that the probability
in that case is smaller, but big enough to find it in a fixed amount of steps. So the same approach is still valid.
This is fairly straightforward. Create a random permutation of the nodes, but interpret the list as follows: Interpret it as a random walk around the nodes, and if node 'b' appears after node 'a', it means that node 'b' appears below node 'a' in the lists:
So if your initial random permutation is
3 2 5 1 4
Then the walk in this case is 3 -> 2 -> 5 -> 1 -> 4 and you creates the rows as follows:
Row 1: 1 2 3 4 5
Row 2: 4 5 2 3 1
This random walk will satisfy both conditions.
But do you wish to allow more than one cycle in your network? I know you don't want two people to have each other's hat. But what about 7 people, where 3 of them have each other's hats and the other 4 have each other's hats? Is this acceptable and/or desirable?
Andrey has already pointed you to randperm and the rejection-sampling-like approach. After generating a permutation p, an easy way to check whether it has fixed point is any(p==1:n). An easy way to check whether it contains cycles of length 2 is any(p(p)==1:n).
So this gets permutations p of 1:n fulfilling your requirements:
p=[];
while (isempty(p))
p=randperm(n);
if any(p==1:n), p=[];
elseif any(p(p)==1:n), p=[];
end
end
Surrounding this with a for loop and for each counting the iterations of the while loop, it seems that one needs to generate on average 4.5 permutations for every "valid" one (and 6.2 if cycles of length three are not allowed, either). Very interesting.

Finding good heuristic for A* search

I'm trying to find the optimal solution for a little puzzle game called Twiddle (an applet with the game can be found here). The game has a 3x3 matrix with the number from 1 to 9. The goal is to bring the numbers in the correct order using the minimum amount of moves. In each move you can rotate a 2x2 square either clockwise or counterclockwise.
I.e. if you have this state
6 3 9
8 7 5
1 2 4
and you rotate the upper left 2x2 square clockwise you get
8 6 9
7 3 5
1 2 4
I'm using a A* search to find the optimal solution. My f() is simply the number of rotations needed. My heuristic function already leads to the optimal solution (if I modify it, see the notice a t the end) but I don't think it's the best one you can find. My current heuristic takes each corner, looks at the number at the corner and calculates the manhatten distance to the position this number will have in the solved state (which gives me the number of rotation needed to bring the number to this postion) and sums all these values. I.e. You take the above example:
6 3 9
8 7 5
1 2 4
and this end state
1 2 3
4 5 6
7 8 9
then the heuristic does the following
6 is currently at index 0 and should by at index 5: 3 rotations needed
9 is currently at index 2 and should by at index 8: 2 rotations needed
1 is currently at index 6 and should by at index 0: 2 rotations needed
4 is currently at index 8 and should by at index 3: 3 rotations needed
h = 3 + 2 + 2 + 3 = 10
Additionally, if h is 0, but the state is not completely ordered, than h = 1.
But there is the problem, that you rotate 4 elements at once. So there a rare cases where you can do two (ore more) of theses estimated rotations in one move. This means theses heuristic overestimates the distance to the solution.
My current workaround is, to simply excluded one of the corners from the calculation which solves this problem at least for my test-cases. I've done no research if really solves the problem or if this heuristic still overestimates in some edge-cases.
So my question is: What is the best heuristic you can come up with?
(Disclaimer: This is for a university project, so this is a bit of homework. But I'm free to use any resource if can come up with, so it's okay to ask you guys. Also I will credit Stackoverflow for helping me ;) )
Simplicity is often most effective. Consider the nine digits (in the rows-first order) as forming a single integer. The solution is represented by the smallest possible integer i(g) = 123456789. Hence I suggest the following heuristic h(s) = i(s) - i(g). For your example, h(s) = 639875124 - 123456789.
You can get an admissible (i.e., not overestimating) heuristic from your approach by taking all numbers into account, and dividing by 4 and rounding up to the next integer.
To improve the heuristic, you could look at pairs of numbers. If e.g. in the top left the numbers 1 and 2 are swapped, you need at least 3 rotations to fix them both up, which is a better value than 1+1 from considering them separately. In the end, you still need to divide by 4. You can pair up numbers arbitrarily, or even try all pairs and find the best division into pairs.
All elements should be taken into account when calculating distance, not just corner elements. Imagine that all corner elements 1, 3, 7, 9 are at their home, but all other are not.
It could be argued that those elements that are neighbors in the final state should tend to become closer during each step, so neighboring distance can also be part of heuristic, but probably with weaker influence than distance of elements to their final state.

Resources