林韋旭
林韋旭

Reputation: 11

h(n) selection in A* algorithm for 2x2 rubik's cube solving

I am currently working on a 2x2 Rubik's cube solving robot project. It takes in the cube data via a 2x2 color sensor array and solves it using some servo motors and arms. I was looking on wiki and I think A* would be a possible way to write the program to solve it. However, I can't figure out how to define the expected cost function(h) for the cube. It isn't finding the shortest path on a 2D plane, where h(n) can simply be some form of actual distance(Euclidean, Manhattan, etc). I was originally thinking about counting how many tiles have already grouped up, but it won't really work since I can just do 2~3 moves on the cube and many tiles are disconnected. How exactly should I write this cost function? Or is there a better alternative to A* in my case? (2x2 is too simple to use IDA*, I guess. The max possible move count to solve it is only 11)

Upvotes: 1

Views: 1994

Answers (1)

benbotto
benbotto

Reputation: 2439

A* with iterative-deepening, depth-first search (IDA*) is a good way to go. For the heuristic, define one or more pattern databases, where each key is a cube state, and each value is the distance to the solved state from that cube state. To keep the databases reasonably small, each database can hold a subset of the cube's overall state. Regarding the heuristic, given a cube state, look up the distance in every database. The maximum of those distances is the best estimated distance to the solved state (i.e. it takes at least that many moves to solve the cube).

For example, one could make a database that has the orientations of all 8 cubies. Just the orientations mind you, not the positions. Since each piece can be in one of three orientations--on the top layer, any sticker can point up, for example--there are 3^8 possible states. I'm not an expert in the 2x2, but I'm pretty sure that it's impossible to disorient just one piece. That is, it's not possible to have a solved 2x2 and then flip just one cubie. Assuming that's correct, there are actually 3^7=2187 possible orientation states. You would then iterate using BFS from the solved state and find each of these 2187 states, encode each state into an integer from 0-2186, and store the distance from that state to the solved state. Put another way, a database is just a hash table.

You could make multiple databases in the same manner. For example, the positions of the 8 pieces. The positions and orientations of 4 of the 8 pieces. Etc.

When it comes time to solve the cube, use IDA*. Each time a state is encountered, check the maximum distance provided from all of the pattern databases. There's your heuristic function. Prune accordingly.

I have an article on Medium that goes into a lot more detail, but it's for the 3x3. The same strategy works, though.

P.s. The 2x2 is small enough that one can make a perfect pattern database with the exact distance from each state to the solved state and store that database on disk in only 1.8MB. (There are 3,674,160 states, with a God's number of 11. 11 can fit in a nibble. 3,674,160/1024^2/2 ~= 1.8MB.) With that database, IDA* would be able to solve the 2x2 effectively instantaneously.

Upvotes: 2

Related Questions