Calculating the Manhattan distance in the eight puzzle
Summing over each number's Manhatten distance:
>>> board = [7, 2, 4, 5, 0, 6, 8, 3, 1]
>>> sum(abs((val-1)%3 - i%3) + abs((val-1)//3 - i//3)
for i, val in enumerate(board) if val)
14
For example, the 7 belongs at (zero-based) coordinate (0, 2) = ((7-1)%3
, (7-1)//3
) but is at coordinate (0, 0), so add abs(0 - 0) + abs(2 - 0)
for it.
For non-standard goals:
>>> goal = [1, 2, 3, 8, 0, 4, 7, 6, 5]
>>> sum(abs(b%3 - g%3) + abs(b//3 - g//3)
for b, g in ((board.index(i), goal.index(i)) for i in range(1, 9)))
16
Is there a more efficient algorithm to calculate the Manhattan distance of a 8-puzzle game?
It looks to me like you should only need to calculate the full Manhattan distance sum for an entire board once - for the first board. After that, you're creating new Board
entities from existing ones by swapping two adjacent numbers. The total Manhattan distance on the new board will differ only by the sum of changes in Manhattan distance for these two numbers.
If one of the numbers is the blank (0
), then the total distance changes by minus one or one depending on whether the non-blank number moved closer to its proper place or farther from it. If both of the numbers are non-blank, as when you're making "twins", the total distance changes by minus two, zero, or two.
Here's what I would do: add a manhattan_distance = None
argument to Board.__init__
. If this is not given, calculate the board's total Manhattan distance; otherwise simply store the given distance. Create your first board without this argument. When you create a new board from an existing one, calculate the change in the total distance and pass the result in to the new board. (The cached_manhattan
becomes irrelevant.)
This should reduce the total number of calculations involved with distance by quite a bit - I'd expect it to speed things up by several times, more the larger your board size.
8 Puzzle Game - finding position in 2d array
Manhattan could using a reverse lookup table.
Code
def manhattan_distance(self, other):
' Distance between where tiles are and where they should be '
# Generate reverse lookup table so we know where each item should be located
lookup_loc = {}
if i in range(3):
for j in range(3):
# other.board[i][j] is the value
# which has location at (i, j)
lookup_loc[other.board[i][j]] = (i, j)
dist = 0
for i in range(3):
for j in range(3):
if self.board[i][j] != other.board[i][j]:
# Find correct location for value self.board[i][j]
correct_loc = lookup_loc[self.board[i][j]]
# Manhattan distance between current location (i, j) and
# correction location
dist += abs(correct_loc[0]-i) + abs(correct_loc[1] - j)
return dist
Calculate Manhattan distance for n_puzzle problem?
Let's say the misplace tile is in position (x, y), while the correct position should be (w, z). The number of moves required to move the tile to the correct position is:
n_moves = abs(x - w) + abs(y - z)
Manhattan distance in A*
I was stuck in the same place sometime back where I was solving this in 17 moves.The problem was that I was only using heuristic h(n) for the A* algorithm and whereas for choosing the next node A* uses manhattan distance(heuristic) + pathcost (cost to reach the node from root called as g(n)) to make the choice.
Once you plug in this to the algorithm it works like a charm.
Hope this helps someone who is stuck in the same place.
8Puzzle game with A* : What structure for the open set?
The open set should be a priority queue. Typically these are implemented using a binary heap, though other implementations exist.
Neither an array-list nor a dictionary would be efficient.
The closed set should be an efficient set, so usually a hash table or binary search tree, depending on what your language's standard library defaults to.
A dictionary (aka "map") would technically work, but it's conceptually the wrong data-structure because you're not mapping to anything. An array-list would not be efficient.
Related Topics
Import Error: Dll Load Failed in Jupyter Notebook But Working in .Py File
How to Resolve Modulenotfounderror: No Module Named 'Google.Colab'
Typing Greek Letters etc. in Plots
Python Opencv Cv2 - How to Increase the Brightness and Contrast of an Image by 100%
How to Send Smtp Email for Office365 With Python Using Tls/Ssl
How to Center a Window on the Screen in Tkinter
How to Delete Comma At the End of the Output in Python
Text Pre-Processing + Python + Csv:Removing Special Characters from a Column of a Csv
How to Change the Foreground or Background Colour of a Tkinter Button on MAC Os X
How to Make Tkinter Frames in a Loop and Update Object Values
When to Use Cla(), Clf() or Close() for Clearing a Plot in Matplotlib
How to Delete Quotes from Data Read from .Csv File
How to Remove Grid Lines on Image in Python
Python/Pandas: How to Match List of Strings With a Dataframe Column
What Causes a Python Segmentation Fault
Python Serial: How to Use the Read or Readline Function to Read More Than 1 Character At a Time