Problem definition:
An 8 puzzle is a simple game consisting of a 3 x
3 grid (containing 9 squares). One of the squares is empty. The object is to
move to squares around into different positions and having the numbers
displayed in the "goal state".
Given an initial state of 8-puzzle game and a final state of
to be reached, find the most cost-effective path to reach the final state from
initial state.
Initial state:
5 4 _
6 1 8
7 3 2
Final state:
1 2 3
8 _ 4
7 3 5
Solution 8 Puzzle:
The puzzle can be solved by moving the tiles one by one in
the single empty space and thus achieving the Goal state.
Rules of solving
puzzle
Instead of moving the tiles in the empty space we can
visualize moving the empty space in place of the tile. The empty space can
only move in four directions (Movement of empty space)
1.     
Up 
2.     
Down 
3.     
Right or
4.     
Left
The empty space cannot move diagonally and can
take only one step at a time. All possible move of an Empty tile

o- Position total possible moves are (2), x -
position total possible moves are (3) and 
#-position total possible moves are (4)
Let's solve the problem without Heuristic
Search that is Uninformed Search or Blind Search ( Breadth
First Search and Depth
First Search)
If we solve this problem with depth first search, then it
will go to depth instead of exploring layer wise nodes.
Time complexity: In worst case time complexity
in BFS is O(b^d) know as order of b raise to power d.  In
this particular case it is (3^20). 
b-branch factor
d-depth factor
Let's solve the problem with Heuristic Search that
is Informed Search (A* , Best
First Search (Greedy Search))
To solve the problem with Heuristic search or informed search
we have to calculate Heuristic values of each node to calculate cost
function. (f=g+h)
See the initial state and goal state carefully all values
except (4,5 and 8) are at their respective places. so, the heuristic
value for first node is 3.(Three values are misplaced to reach the goal). And
let's take actual cost (g) according to depth.
Because of quick solution time complexity is less than that of Uninformed
search but optimal solution not possible. 
Python
Code:
import random
import math
_goal_state = [[1,2,3],
              
[8,0,4],
              
[7,6,5]]
def index(item, seq):
   
"""Helper function that returns -1 for non-found index
value of a seq"""
    if item in
seq:
        return
seq.index(item)
    else:
        return
-1
class EightPuzzle:
    def
__init__(self):
        #
heuristic value
       
self._hval = 0
        # search depth of current instance
       
self._depth = 0
        # parent
node in search path
       
self._parent = None
       
self.adj_matrix = []
        for i in
range(3):
           
self.adj_matrix.append(_goal_state[i][:])
    def
__eq__(self, other):
        if
self.__class__ != other.__class__:
           
return False
        else:
           
return self.adj_matrix == other.adj_matrix
    def
__str__(self):
        res = ''
        for row
in range(3):
            res
+= ' '.join(map(str, self.adj_matrix[row]))
            res
+= '\r\n'
        return
res
    def
_clone(self):
        p =
EightPuzzle()
        for i in
range(3):
           
p.adj_matrix[i] = self.adj_matrix[i][:]
        return p
    def _get_legal_moves(self):
       
"""Returns list of tuples with which the free space may
        be
swapped"""
        # get
row and column of the empty piece
        row, col
= self.find(0)
        free =
[]
        
        # find
which pieces can move there
        if row
> 0:
           
free.append((row - 1, col))
        if col
> 0:
           
free.append((row, col - 1))
        if row
< 2:
           
free.append((row + 1, col))
        if col
< 2:
            free.append((row,
col + 1))
        return
free
    def
_generate_moves(self):
        free =
self._get_legal_moves()
        zero =
self.find(0)
        def
swap_and_clone(a, b):
            p =
self._clone()
           
p.swap(a,b)
           
p._depth = self._depth + 1
           
p._parent = self
           
return p
        return
map(lambda pair: swap_and_clone(zero, pair), free)
    def
_generate_solution_path(self, path):
        if
self._parent == None:
           
return path
        else:
           
path.append(self)
           
return self._parent._generate_solution_path(path)
    def
solve(self, h):
       
"""Performs A* search for goal state.
       
h(puzzle) - heuristic function, returns an integer
       
"""
        def
is_solved(puzzle):
           
return puzzle.adj_matrix == _goal_state
        openl =
[self]
        closedl
= []
       
move_count = 0
        while
len(openl) > 0:
            x =
openl.pop(0)
           
move_count += 1
            if
(is_solved(x)):
               
if len(closedl) > 0:
                   
return x._generate_solution_path([]), move_count
               
else:
                   
return [x]
            succ = x._generate_moves()
           
idx_open = idx_closed = -1
            for
move in succ:
               
# have we already seen this node?
               
idx_open = index(move, openl)
               
idx_closed = index(move, closedl)
                hval = h(move)
               
fval = hval + move._depth
               
if idx_closed == -1 and idx_open == -1:
                   
move._hval = hval
                   
openl.append(move)
               
elif idx_open > -1:
                   
copy = openl[idx_open]
                   
if fval < copy._hval + copy._depth:
                       
# copy move's values over existing
                       
copy._hval = hval
                       
copy._parent = move._parent
                       
copy._depth = move._depth
               
elif idx_closed > -1:
                   
copy = closedl[idx_closed]
                   
if fval < copy._hval + copy._depth:
                       
move._hval = hval
                       
closedl.remove(copy)
                       
openl.append(move)
           
closedl.append(x)
           
openl = sorted(openl, key=lambda p: p._hval + p._depth)
        # if
finished state not found, return failure
        return
[], 0
    def
shuffle(self, step_count):
        for i in
range(step_count):
            row,
col = self.find(0)
            free
= self._get_legal_moves()
           
target = random.choice(free)
           
self.swap((row, col), target)           
            row, col = target
    def
find(self, value):
       
"""returns the row, col coordinates of the specified
value
           in
the graph"""
        if value
< 0 or value > 8:
           
raise Exception("value out of range")
        for row
in range(3):
            for
col in range(3):
               
if self.adj_matrix[row][col] == value:
                   
return row, col
    
    def
peek(self, row, col):
       
"""returns the value at the specified row and
column"""
        return self.adj_matrix[row][col]
    def
poke(self, row, col, value):
       
"""sets the value at the specified row and
column"""
       
self.adj_matrix[row][col] = value
    def
swap(self, pos_a, pos_b):
       
"""swaps values at the specified coordinates"""
        temp =
self.peek(*pos_a)
       
self.poke(pos_a[0], pos_a[1], self.peek(*pos_b))
       
self.poke(pos_b[0], pos_b[1], temp)
def heur(puzzle, item_total_calc, total_calc):
   
"""
    Heuristic
template that provides the current and target position for each number and the 
    total
function.
    
    Parameters:
    puzzle - the
puzzle
   
item_total_calc - takes 4 parameters: current row, target row, current
col, target col. 
    Returns int.
    total_calc -
takes 1 parameter, the sum of item_total_calc over all entries, and returns
int. 
    This is the
value of the heuristic function
   
"""
    t = 0
    for row in
range(3):
        for col
in range(3):
            val
= puzzle.peek(row, col) - 1
           
target_col = val % 3
           
target_row = val / 3
            #
account for 0 as blank
            if
target_row < 0: 
               
target_row = 2
            t +=
item_total_calc(row, target_row, col, target_col)
    return
total_calc(t)
#some heuristic functions, the best being the standard
manhattan distance in this case, as it comes
#closest to maximizing the estimated distance while
still being admissible.
def h_manhattan(puzzle):
    return heur(puzzle,
               
lambda r, tr, c, tc: abs(tr - r) + abs(tc - c),
               
lambda t : t)
def h_manhattan_lsq(puzzle):
    return
heur(puzzle,
               
lambda r, tr, c, tc: (abs(tr - r) + abs(tc - c))**2,
               
lambda t: math.sqrt(t))
def h_linear(puzzle):
    return
heur(puzzle,
               
lambda r, tr, c, tc: math.sqrt(math.sqrt((tr - r)**2 + (tc - c)**2)),
               
lambda t: t)
def h_linear_lsq(puzzle):
    return
heur(puzzle,
               
lambda r, tr, c, tc: (tr - r)**2 + (tc - c)**2,
               
lambda t: math.sqrt(t))
def h_default(puzzle):
    return 0
def main():
    p =
EightPuzzle()
   
p.shuffle(20)
    print (p)
    path, count
= p.solve(h_manhattan)
    path.reverse()
    for i in
path: 
        print
(i)
    print
("Solved with Manhattan distance exploring", count,
"states")
    path, count
= p.solve(h_manhattan_lsq)
    print
("Solved with Manhattan least squares exploring", count,
"states")
    path, count
= p.solve(h_linear)
    print
("Solved with linear distance exploring", count, "states")
    path, count
= p.solve(h_linear_lsq)
    print
("Solved with linear least squares exploring", count,
"states")
#    path, count
= p.solve(heur_default)
#    print
"Solved with BFS-equivalent in", count, "moves"
if __name__ == "__main__":
    main()
Python Output:
C++ Code: 
#include <bits/stdc++.h>
using namespace std;
#define N 3
// state space tree nodes
struct Node
{
         //
stores the parent node of the current node
         // helps
in tracing path when the answer is found
         Node*
parent;
         //
stores matrix
         int
mat[N][N];
         //
stores blank tile coordinates
         int x,
y;
         //
stores the number of misplaced tiles
         int
cost;
         //
stores the number of moves so far
         int
level;
};
// Function to print N x N matrix
int printMatrix(int mat[N][N])
{
         for (int
i = 0; i < N; i++)
         {
                 for
(int j = 0; j < N; j++)
                          printf("%d
", mat[i][j]);
                 printf("\n");
         }
}
// Function to allocate a new node
Node* newNode(int mat[N][N], int x, int y, int newX,
                          int
newY, int level, Node* parent)
{
         Node*
node = new Node;
         // set
pointer for path to root
         node->parent
= parent;
         // copy
data from parent node to current node
         memcpy(node->mat,
mat, sizeof node->mat);
         // move
tile by 1 position
         swap(node->mat[x][y],
node->mat[newX][newY]);
         // set
number of misplaced tiles
         node->cost
= INT_MAX;
         // set
number of moves so far
         node->level
= level;
         //
update new blank tile cordinates
         node->x
= newX;
         node->y
= newY;
         return
node;
}
// bottom, left, top, right
int row[] = { 1, 0, -1, 0 };
int col[] = { 0, -1, 0, 1 };
// Function to calculate the number of misplaced tiles
// ie. number of non-blank tiles not in their goal
position
int calculateCost(int initial[N][N], int final[N][N])
{
         int
count = 0;
         for (int
i = 0; i < N; i++)
         for (int
j = 0; j < N; j++)
                 if
(initial[i][j] && initial[i][j] != final[i][j])
                 count++;
         return
count;
}
// Function to check if (x, y) is a valid matrix
cordinate
int isSafe(int x, int y)
{
         return
(x >= 0 && x < N && y >= 0 && y < N);
}
// print path from root node to destination node
void printPath(Node* root)
{
         if (root
== NULL)
                 return;
         printPath(root->parent);
         printMatrix(root->mat);
         printf("\n");
}
// Comparison object to be used to order the heap
struct comp
{
         bool
operator()(const Node* lhs, const Node* rhs) const
         {
                 return
(lhs->cost + lhs->level) > (rhs->cost + rhs->level);
         }
};
// Function to solve N*N - 1 puzzle algorithm using
// Branch and Bound. x and y are blank tile
coordinates
// in initial state
void solve(int initial[N][N], int x, int y,
                 int
final[N][N])
{
         //
Create a priority queue to store live nodes of
         //
search tree;
         priority_queue<Node*,
std::vector<Node*>, comp> pq;
         //
create a root node and calculate its cost
         Node*
root = newNode(initial, x, y, x, y, 0, NULL);
         root->cost
= calculateCost(initial, final);
         // Add
root to list of live nodes;
         pq.push(root);
         // Finds
a live node with least cost,
         // add
its childrens to list of live nodes and
         //
finally deletes it from the list.
         while
(!pq.empty())
         {
                 //
Find a live node with least estimated cost
                 Node*
min = pq.top();
                 //
The found node is deleted from the list of
                 //
live nodes
                 pq.pop();
                 //
if min is an answer node
                 if
(min->cost == 0)
                 {
                          //
print the path from root to destination;
                          printPath(min);
                          return;
                 }
                 //
do for each child of min
                 //
max 4 children for a node
                 for
(int i = 0; i < 4; i++)
                 {
                          if
(isSafe(min->x + row[i], min->y + col[i]))
                          {
                                   //
create a child node and calculate
                                   //
its cost
                                   Node*
child = newNode(min->mat, min->x,
                                                             min->y,
min->x + row[i],
                                                             min->y
+ col[i],
                                                             min->level
+ 1, min);
                                   child->cost
= calculateCost(child->mat, final);
                                   //
Add child to list of live nodes
                                   pq.push(child);
                          }
                 }
         }
}
// Driver code
int main()
{
         //
Initial configuration
         // Value
0 is used for empty space
         int initial[N][N]
=
         {
                 {1,
2, 3},
                 {5,
6, 0},
                 {7,
8, 4}
         };
         //
Solvable Final configuration
         // Value
0 is used for empty space
         int
final[N][N] =
         {
                 {1,
2, 3},
                 {8,
0, 4},
                 {7,
6, 5}
         };
         // Blank
tile coordinates in initial
         // configuration
         int x =
1, y = 2;
         solve(initial,
x, y, final);
         return
0;
}
 


 
 
 
![এক্সএমএল - XML : ৮ [XML Elements]](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisymurbCebTBxApDvlyc-eLtsgysafLxdPpmO87iLj1jba_Lqf8hmCQKIE8gZKDJGF7kxbtp5zZdkwwudi4-xcNbcbgRiSrKcfEngGTMdySQn8O36QawRkYewevV3PnWhBCmpYr6ROs-uifpKee8WlfIPcLZ-IDlA1sucBcl7Lfp9wFjp7mAYU4wGlSier/s72-c/image.png) 
![এক্সএমএল - XML : ৭ [XML Tree, XML Syntax]](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmqbhhcIBSKP0FsgizxpqgcpflVV6MdhugNnZ45N_u6ecEDHH1z_2Y3KtNUdVPAOqazWQtn7engNJHKWm0SgXEQSNe5ljqxJ_16IQHbFJ3Gng8PaqEqCVOpnuIIpS0k2JdvzseaVviFve1BiDS_wnthJ-s_Q-PBc_WynPjh1BBZ70bEMATalaahrxsUE49/s72-c/image.png) 
![জাভাস্ক্রিপ্ট-৬ [কমেন্ট, অপারেটর]](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyb8n_zvJUyWrdYaZlstACeLt5P2QU4AFzxuIhSFoEStv2aKMKiPKY3YhV4sbNlINE6CDRduDEOhcz6aIvrSfbIQUJoaYRFlN74DWmJdp8AHGGBrebktvrCLsw1AEExtqjOT7Ef6ayrOPt2Xu0K5pgUr4CqOt04lImf4bl7kvu5e4UE3NVz0hTLzb0tX7i/s72-w370-c-h277/image.png)