Advertisement
TRADECTO

LAB4

Nov 20th, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.46 KB | None | 0 0
  1. import time
  2. from collections import deque
  3.  
  4. ## The Class that Represents the Puzzle
  5.  
  6. class PuzzleState(object):
  7.     """PuzzleState class"""
  8.     def __init__(self, config, n, parent=None, action="Initial"):
  9.         if n*n != len(config) or n < 2:
  10.             raise Exception("the length of config is not correct!")
  11.         self.n = n
  12.         self.parent = parent
  13.         self.action = action
  14.         self.config = config
  15.         self.children = []
  16.         self.cost = self.calculate_total_cost()
  17.         for i, item in enumerate(self.config):
  18.             if item == 0:
  19.                 self.blank_row = int( i / self.n )
  20.                 self.blank_col = i % self.n
  21.                 break
  22.  
  23.     def get_history(self):
  24.         self.history = []
  25.         self.next = self
  26.         #print(self.next)
  27.         while self.next.parent is not None:
  28.             self.history.append(self.next)
  29.             self.next = self.next.parent
  30.         self.history.reverse()
  31.         return self.history
  32.         """
  33.     def calculate_manhattan_dist(self):
  34.         self.dist = 0
  35.         for i in range(self.n**2):
  36.             self.dist += abs(self.config[i]-i)
  37.         return self.dist
  38.         """
  39.     def calculate_manhattan_dist(self):
  40.         result = 0
  41.         true_state = [0,1,2,3,4,5,6,7,8]
  42.         for i in range(len(self.config)):
  43.             x = (abs(true_state.index(self.config[i]))) // 3
  44.             y = (abs(true_state.index(self.config[i]))) % 3
  45.             x1 = i // 3
  46.             y1 = i % 3
  47.             result += (abs(x - x1) + abs(y-y1))
  48.         return result
  49.  
  50.  
  51.     def calculate_cost(self):
  52.         return len(self.get_history())
  53.  
  54.     def calculate_total_cost(self):
  55.         return self.calculate_manhattan_dist() + self.calculate_cost()
  56.  
  57.  
  58.     def display(self):
  59.         for i in range(self.n):
  60.             line = []
  61.             offset = i * self.n
  62.             for j in range(self.n):
  63.                 line.append(self.config[offset + j])
  64.             print(line)
  65.  
  66.     def move_left(self):
  67.         if self.blank_col == 0:
  68.             return None
  69.         else:
  70.             blank_index = int(self.blank_row * self.n + self.blank_col)
  71.             target = blank_index - 1
  72.             new_config = list(self.config)
  73.             new_config[blank_index], new_config[target] = new_config[target], new_config[blank_index]
  74.             return PuzzleState(tuple(new_config), self.n, parent=self, action="Left")
  75.  
  76.     def move_right(self):
  77.         if self.blank_col == self.n - 1:
  78.             return None
  79.         else:
  80.             blank_index = int(self.blank_row * self.n + self.blank_col)
  81.             target = blank_index + 1
  82.             new_config = list(self.config)
  83.             new_config[blank_index], new_config[target] = new_config[target], new_config[blank_index]
  84.             return PuzzleState(tuple(new_config), self.n, parent=self, action="Right")
  85.  
  86.     def move_up(self):
  87.         if self.blank_row == 0:
  88.             return None
  89.         else:
  90.             blank_index = int(self.blank_row * self.n + self.blank_col)
  91.             target = blank_index - self.n
  92.             new_config = list(self.config)
  93.             new_config[blank_index], new_config[target] = new_config[target], new_config[blank_index]
  94.             return PuzzleState(tuple(new_config), self.n, parent=self, action="Up")
  95.  
  96.     def move_down(self):
  97.         if self.blank_row == self.n - 1:
  98.             return None
  99.         else:
  100.             blank_index = int(self.blank_row * self.n + self.blank_col)
  101.             target = blank_index + self.n
  102.             new_config = list(self.config)
  103.             new_config[blank_index], new_config[target] = new_config[target], new_config[blank_index]
  104.             return PuzzleState(tuple(new_config), self.n, parent=self, action="Down")
  105.  
  106.     def expand(self):
  107.         """expand the node"""
  108.         # add child nodes in order of UDLR
  109.         if len(self.children) == 0:
  110.             up_child = self.move_up()
  111.             if up_child is not None:
  112.                 self.children.append(up_child)
  113.  
  114.             down_child = self.move_down()
  115.             if down_child is not None:
  116.                 self.children.append(down_child)
  117.  
  118.             left_child = self.move_left()
  119.             if left_child is not None:
  120.                 self.children.append(left_child)
  121.  
  122.             right_child = self.move_right()
  123.             if right_child is not None:
  124.                 self.children.append(right_child)
  125.  
  126.         return self.children
  127.  
  128.     def state(self):
  129.         return self.config
  130.  
  131.     def test_goal(self):
  132.         return self.config == (0,1,2,3,4,5,6,7,8)
  133.  
  134.  
  135. ### STUDENT CODE GOES HERE ###
  136.  
  137. def get_history(state):
  138.     history = []
  139.     while state.parent is not None:
  140.         history.append(state)
  141.         state = state.parent
  142.     history.reverse()
  143.     return history
  144.  
  145. def display(state):
  146.     config = state.state()
  147.     return "{} {} {}\n{} {} {}\n{} {} {}".format(config[0],config[1],config[2],config[3],config[4],config[5],config[6],config[7],config[8])
  148.  
  149.  
  150. def bfs_search(initial_state):
  151.     """BFS search"""
  152.  
  153.     queue = deque()
  154.     queue.append(initial_state)
  155.     explored = set()
  156.  
  157.     while (len(queue) != 0):
  158.  
  159.         state = queue.popleft()
  160.         explored.add(state.state())
  161.  
  162.         if state.test_goal():
  163.             q = len(list(elem.state() for elem in queue))
  164.             e = len(explored)
  165.             return state, q, e
  166.  
  167.         for neighbour in state.expand():
  168.            if ((neighbour.state() not in queue) and (neighbour.state() not in explored)):
  169.                queue.append(neighbour)
  170.  
  171.     return False
  172.  
  173.  
  174. def dfs_search(initial_state):
  175.  
  176.     queue = []
  177.     queue.append(initial_state)
  178.     explored = set()
  179.  
  180.     while (len(queue) != 0):
  181.  
  182.         state = queue.pop()
  183.         explored.add(state.state())
  184.  
  185.         if state.test_goal():
  186.             q = len(list(elem.state() for elem in queue))
  187.             e = len(explored)
  188.             return state, q, e
  189.  
  190.         for neighbour in state.expand():
  191.            if ((neighbour.state() not in queue) and (neighbour.state() not in explored)):
  192.                queue.append(neighbour)
  193.  
  194.     return False
  195.  
  196. """
  197. def calculate_manhattan_dist(state,n):
  198.     dist = 0
  199.     for i in range(n**2):
  200.         dist += abs(state[i]-i)
  201.     return dist
  202.  
  203. def calculate_cost(state):
  204.     return len(get_history(state))
  205.  
  206. def calculate_total_cost(state,n):
  207.     return calculate_manhattan_dist(state.config,n) + calculate_cost(state)
  208. """
  209.  
  210. def a_star_search(initial_state):
  211.     queue = []
  212.     queue.append(initial_state)
  213.     explored = set()
  214.  
  215.     while (len(queue) != 0):
  216.         queue.sort(key=lambda x: x.cost, reverse=False)
  217.  
  218.         #input()
  219.         state = queue.pop(0)
  220.         explored.add(state.state())
  221.  
  222.         if state.test_goal():
  223.             q = len(list(elem.state() for elem in queue))
  224.             e = len(explored)
  225.             return state, q, e
  226.  
  227.         for neighbour in state.expand():
  228.            if ((neighbour.state() not in queue) and (neighbour.state() not in explored)):
  229.                queue.append(neighbour)
  230.  
  231.     return False
  232.  
  233. def main():
  234.     start_state = PuzzleState((8,6,4,2,1,3,5,7,0),3)
  235.     #print(start_state.calculate_manhattan_dist())
  236.     state,q,e = a_star_search(start_state)
  237.     history = state.get_history()
  238.  
  239.     for elem in history:
  240.         print("-----------")
  241.         print(display(elem))
  242.     print("-----------")
  243.     print("Total moves: ",len(history))
  244.     print("Total nodes explored: ", e)
  245.     print("Total nodes opened: ", q)
  246.  
  247. if __name__ == '__main__':
  248.     start_time = time.time()
  249.     main()
  250.     running_time = time.time() - start_time
  251.     print('running time:', running_time)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement