Find the minimum number of moves needed to move from one cell of matrix to another in Python


Suppose we have one N X N matrix M, and this is filled with 1, 0, 2, 3, We have to find the minimum numbers of moves required to move from source cell to destination cell. While visiting through blank cells only, we can visit up, down, right and left.

  • Cell with value 1 indicates Source.

  • Cell with value 2 indicates Destination.

  • Cell with value 3 indicates Blank cell.

  • Cell with value 0 indicates Blank Wall.

There will be only one source and only one destination cells. There may be more than one path to reach destination from source cell. Now, each move in matrix we consider as '1'.

So, if the input is like

3310
3033
3303
0323

then the output will be 5,

3310
3033
3303
0323

From start to destination the green path is shortest.

To solve this, we will follow these steps −

  • nodes := order * order + 2

  • g := a blank graph with ‘nodes’ number of vertices

  • k := 1

  • for i in range 0 to order, do

    • for j in range 0 to order, do

      • if mat[i, j] is not same as 0, then

        • if is_ok (i , j + 1 , mat) is non-zero, then

          • create an edge between k and k + 1 nodes of g

        • if is_ok (i , j - 1 , mat) is non-zero, then

          • create an edge between k, k - 1 nodes of g

        • if j < order - 1 and is_ok (i + 1 , j , mat) is non-zero, then

          • create an edge between k, k + order nodes of g

        • if i > 0 and is_ok (i - 1 , j , mat) is non-zero, then

          • create an edge between k, k - order nodes of g

      • if mat[i, j] is same as 1, then

        • src := k

      • if mat[i, j] is same as 2, then

        • dest := k

      • k := k + 1

  • return perform bfs from src to dest of g

Example 

Let us see the following implementation to get better understanding −

 Live Demo

class Graph:
   def __init__(self, nodes):
      self.nodes = nodes
      self.adj = [[] for i in range(nodes)]
   def insert_edge (self, src , dest):
      self.adj[src].append(dest)
      self.adj[dest].append(src)
   def BFS(self, src, dest):
      if (src == dest):
         return 0
      level = [-1] * self.nodes
      queue = []
      level[src] = 0
      queue.append(src)
      while (len(queue) != 0):
         src = queue.pop()
            i = 0
            while i < len(self.adj[src]):
               if (level[self.adj[src][i]] < 0 or level[self.adj[src][i]] > level[src] + 1 ):
level[self.adj[src][i]] = level[src] + 1 queue.append(self.adj[src][i])
               i += 1
      return level[dest]

def is_ok(i, j, mat):
   global order
   if ((i < 0 or i >= order) or (j < 0 or j >= order ) or mat[i][j] == 0):
      return False
   return True
def get_min_math(mat):
   global order
   src , dest = None, None
   nodes = order * order + 2
   g = Graph(nodes)
   k = 1
   for i in range(order):
      for j in range(order):
         if (mat[i][j] != 0):
            if (is_ok (i , j + 1 , mat)):
               g.insert_edge (k , k + 1)
            if (is_ok (i , j - 1 , mat)):
               g.insert_edge (k , k - 1)
            if (j < order - 1 and is_ok (i + 1 , j , mat)):
               g.insert_edge (k , k + order)
            if (i > 0 and is_ok (i - 1 , j , mat)):
               g.insert_edge (k , k - order)
         if(mat[i][j] == 1):
            src = k
         if (mat[i][j] == 2):
            dest = k
         k += 1
   return g.BFS (src, dest)
order = 4
mat = [[3,3,1,0], [3,0,3,3], [3,3,0,3], [0,3,2,3]]
print(get_min_math(mat))

Input

[[3,3,1,0], [3,0,3,3], [3,3,0,3], [0,3,2,3]]

Output

0

Updated on: 20-Aug-2020

253 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements