21

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 ;) )

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Martin Thurau
  • 7,564
  • 7
  • 43
  • 80

3 Answers3

3

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.

Liberius
  • 148
  • 3
  • Correct me if I'm wrong, but this isn't a useable heuristic for A* since h() needs to (under)estimate the distance to the target. What should I use as distance measurements, if not the needed rotations? – Martin Thurau Jan 01 '11 at 23:10
  • You are quite right. This suggestion of mine is just a hint and also a useful technique in other situations as well. However, it is not difficult to design a real-valued function to satisfy the A* heuristic requirement. For example, h(n) = (i(n)-i(g))/i(s), where n is the current state, g is the goal state, s is the initial state and i is the state value as defined in my answer above. h(g) = 0.0. However, you need to test this. Tell us if it found the optimal solution. – Liberius Jan 02 '11 at 10:54
  • Okay, I've tested it. It seems to overestimate sometimes, because the optimal solution is not found every time. Also this yield values for h() which are around 1. Sometimes the values are higher but there are not high enough to optimize the search in a useful way. Nevertheless a clever tough – Martin Thurau Jan 03 '11 at 08:25
  • OK, thanks. If you just want guaranteed optimal solution, the easiest way to reach it for a smallish problem like this is to set h(n) = 0, which is always guaranteed to underestimate. In fact, this will give you the breadth-first search which, given enough space to store the frontier set, will always find the optimal solution(s). – Liberius Jan 03 '11 at 17:16
  • This is incorrect. This heuristic is not admissable, and scaling down to make it admissable makes it useless. Setting h(x) to 0 works, but then it's no longer A* but DIjkstra (which in this case is equivalent to BFS). – ADdV Feb 25 '21 at 15:35
1

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.

Falk Hüffner
  • 4,942
  • 19
  • 25
0

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.

Dialecticus
  • 16,400
  • 7
  • 43
  • 103
  • You're right. I forgot to mention that h is 1 if all corner elements are are at their home but the total state is not ordered. – Martin Thurau Dec 31 '10 at 15:09