Advertisement
Guest User

Untitled

a guest
Apr 5th, 2020
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.76 KB | None | 0 0
  1. import copy
  2.  
  3. class Queue:
  4.     def __init__(self):
  5.         raise NotImplementedError
  6.  
  7.     def extend(self, items):
  8.         for item in items:
  9.             self.append(item)
  10.  
  11. class FIFOQueue(Queue):
  12.     def __init__(self):
  13.         self.A = []
  14.         self.start = 0
  15.  
  16.     def append(self, item):
  17.         self.A.append(item)
  18.  
  19.     def __len__(self):
  20.         return len(self.A) - self.start
  21.  
  22.     def extend(self, items):
  23.         self.A.extend(items)
  24.  
  25.     def pop(self):
  26.         e = self.A[self.start]
  27.         self.start += 1
  28.         if self.start > 5 and self.start > len(self.A) / 2:
  29.             self.A = self.A[self.start:]
  30.             self.start = 0
  31.         return e
  32.  
  33.     def __contains__(self, item):
  34.         return item in self.A[self.start:]
  35.  
  36. def graph_search(problem, fringe):
  37.     closedStates = []
  38.     fringe.append(Node(problem.initial))
  39.     while fringe:
  40.         node = fringe.pop()
  41.         if problem.goal_test(node.state):
  42.             return node
  43.         inside = False
  44.         for state in closedStates:
  45.             if state == node.state:
  46.                 inside = True
  47.                 break
  48.         if not inside:
  49.             fringe.extend(node.expand(problem))
  50.             closedStates.append(node.state)
  51.     return None
  52.  
  53. def breadth_first_graph_search(problem):
  54.     return graph_search(problem, FIFOQueue())
  55.  
  56. class DisksProblem:
  57.     def __init__(self, initial, goal=None, size=4):
  58.         self.initial = initial
  59.         self.goal = goal
  60.         self.size = size
  61.  
  62.     def actions(self,state):
  63.         actions = []
  64.         for idx, element in enumerate(state):
  65.             if element is None:
  66.                 continue
  67.             if idx > 0:
  68.                 if state[idx - 1] is None:
  69.                     actions.append('L1: ' + element)
  70.             if idx > 1:
  71.                 if state[idx - 2] is None and state[idx - 1] is not None:
  72.                     actions.append('L2: ' + element)
  73.             if idx < len(state) - 1:
  74.                 if state[idx + 1] is None:
  75.                     actions.append('D1: ' + element)
  76.             if idx < len(state) - 2:
  77.                 if state[idx + 2] is None and state[idx + 1] is not None:
  78.                     actions.append('D2: ' + element)
  79.         return  actions
  80.  
  81.     def result(self, state, action):
  82.         split_action = action.split(': ')
  83.         operation = split_action[0]
  84.         element_to_move = split_action[1]
  85.         new_state = copy.deepcopy(state)
  86.         for idx, element in enumerate(state):
  87.             if element == element_to_move:
  88.                 new_state[idx] = None
  89.                 if operation == "D1": new_state[idx + 1] = element
  90.                 if operation == "D2": new_state[idx + 2] = element
  91.                 if operation == "L1": new_state[idx - 1] = element
  92.                 if operation == "L2": new_state[idx - 2] = element
  93.         return new_state
  94.  
  95.     def goal_test(self, state):
  96.         return state == self.goal
  97.  
  98.     def path_cost(self, cost, state1, action, state2):
  99.         return cost + 1
  100.  
  101. class Node:
  102.     def __init__(self, state, parent=None
  103.                  , action=None, path_cost=0):
  104.         self.state = state
  105.         self.parent = parent
  106.         self.action = action
  107.         self.path_cost = path_cost
  108.         self.depth = 0
  109.         if parent:
  110.             self.depth = parent.depth + 1
  111.  
  112.     def __repr__(self):
  113.         return "<Node %s>" % (self.state,)
  114.  
  115.     def __lt__(self, other):
  116.         return self.state < other.state
  117.  
  118.     def expand(self, problem):
  119.         return [self.child_node(problem, action)
  120.                 for action in problem.actions(self.state)]
  121.  
  122.     def child_node(self, problem , action):
  123.         next = problem.result(self.state, action)
  124.         return Node(next, self, action, problem.path_cost(self.path_cost, self.state, action, next))
  125.  
  126.     def solution(self):
  127.         return [node.action for node in self.path()[1:]]
  128.  
  129.     def solve(self):
  130.         return [node.state for node in self.path()[0:]]
  131.  
  132.     def path(self):
  133.         x = self
  134.         result = []
  135.         while x:
  136.             result.append(x)
  137.             x = x.parent
  138.         return list(reversed(result))
  139.  
  140.     def __eq__(self, other):
  141.         return isinstance(other, Node) and self.state == other.state
  142.  
  143. n = input("")
  144. l = input("")
  145. initial_state = [ None for y in range(l) ]
  146. goal_state = [ None for y in range(l) ]
  147. for idx in range(0, n):
  148.     element = 'Disk ' + str(idx + 1)
  149.     initial_state[idx] = element
  150.     goal_state[l - 1 - idx] = element
  151.  
  152. print initial_state
  153. print goal_state
  154.  
  155. disks_problem = DisksProblem(initial=initial_state, goal=goal_state)
  156. # print(disks_problem.actions(initial_state))
  157. answer = breadth_first_graph_search(disks_problem)
  158. path = answer.solve()
  159. for item in path:
  160.     print (item)
  161. print (answer.solution())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement