Guest User

Untitled

a guest
Dec 13th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.53 KB | None | 0 0
  1. from .utils import pretty_matrix
  2.  
  3. from abc import ABC, abstractmethod
  4. import numpy as np
  5.  
  6. from operator import itemgetter
  7. from functools import total_ordering
  8.  
  9. class State(tuple):
  10. __slots__ = []
  11. def __new__(cls, index, action, cost):
  12. return tuple.__new__(cls, (index,action,cost))
  13.  
  14. index = property(itemgetter(0))
  15. action = property(itemgetter(1))
  16. cost = property(itemgetter(2))
  17.  
  18. @staticmethod
  19. def initial(pos):
  20. """
  21. Return state at position pos with null value and cost
  22. """
  23. return State(pos, None, 0)
  24.  
  25. def __repr__(self):
  26. return 'State(index={},action={},cost={})'.format(self.index, self.action, self.cost)
  27.  
  28. class Actions:
  29. values = {
  30. ( 0, 0):'no',
  31. (-1, 0):'up',
  32. (-1, 1):'ur',
  33. ( 0, 1):'rg',
  34. ( 1, 1):'dr',
  35. ( 1, 0):'dw',
  36. ( 1,-1):'dl',
  37. ( 0,-1):'lf',
  38. (-1,-1):'ul',
  39. }
  40.  
  41. @staticmethod
  42. def get(fr,to):
  43. diff = tuple(x-y for x,y in zip(to,fr))
  44. return Actions.values[diff]
  45.  
  46. class MatrixProblem(ABC):
  47. @classmethod
  48. def parse_file(cls,filename, algorithm):
  49. """
  50. Creates MatrtixProblem object from file
  51. """
  52. with open(filename, 'r') as f:
  53. lines = filter(lambda x: x.strip(), f.readlines())
  54.  
  55. mat = np.array([l.split() for l in lines])
  56. return cls(mat, algorithm)
  57.  
  58. @abstractmethod
  59. def get_starting_states(self):
  60. """
  61. Returns the initial STATE of a problem
  62. """
  63. pass
  64.  
  65. @abstractmethod
  66. def is_goal(self, state: State):
  67. """
  68. Returns wether a state is a possible ending
  69. """
  70. pass
  71.  
  72. @abstractmethod
  73. def adjacent(self, state: State):
  74. """
  75. Returns the adjacent STATES to a state
  76. """
  77. pass
  78.  
  79. @abstractmethod
  80. def solve(self):
  81. """
  82. Solve using algorithm
  83. """
  84. pass
  85.  
  86. class AllyGathering(MatrixProblem):
  87. def __init__(self,matrix, algorithm):
  88. self._mat = matrix
  89. self._start = tuple(np.argwhere(matrix == 'R')[0])
  90. self._goal = tuple(np.argwhere(matrix == 'X')[0])
  91. self._algorithm = algorithm
  92.  
  93. def get_starting_states(self):
  94. return (State.initial(self._start),)
  95.  
  96. def is_goal(self, state):
  97. return self._mat[state.index] == 'X'
  98.  
  99. def adjacent(self, state):
  100. pos = state.index
  101. x,y = pos
  102. idxs = filter(
  103. lambda a: a!=pos and self._can_move(a),
  104. ((x+i,y+j) for i in range(-1,2) for j in range(-1,2))
  105. )
  106. return (
  107. State(
  108. index=p,
  109. cost=self._cost_for_value(Actions.get(pos,p)),
  110. action=Actions.get(pos,p)
  111. ) for p in idxs
  112. )
  113.  
  114. def solve(self):
  115. res = self._algorithm.search(self)
  116. return sum(s.cost for s in res.states)
  117.  
  118. def get_goal_position(self):
  119. return self._goal
  120.  
  121. def draw_path(self, path):
  122. n,m = self._mat.shape
  123. mat = self._mat.copy()
  124.  
  125. for i,(p,_,_) in enumerate(path):
  126. mat[p] = i
  127. for i in range(n):
  128. for j in range(m):
  129. print(mat[i,j],end=' ')
  130. print()
  131.  
  132. def _cost_for_value(self,value):
  133. if value in ('lf','rg'):
  134. return 5
  135. elif value in ('up','dw'):
  136. return 6
  137. else:
  138. return 10
  139.  
  140. def __contains__(self, pos):
  141. x, y = pos
  142. n, m = self._mat.shape
  143. return x >= 0 and y >= 0 and x < n and y < m
  144.  
  145. def _can_move(self, pos):
  146. return pos in self and self._mat[pos] != '*'
  147.  
  148. class ConqueringProblem(MatrixProblem):
  149. def __init__(self,matrix, algorithm):
  150. self._mat = matrix
  151. self._enemies = np.argwhere(matrix == '.')
  152. self._idx_dict = {tuple(x):i for i,x in enumerate(self._enemies)}
  153. self._algorithm = algorithm
  154.  
  155. def get_starting_states(self):
  156. """
  157. Returns the initial STATE of a problem
  158. """
  159. return list(self._get_border_enemies())
  160.  
  161. def is_goal():
  162. raise Exception()
  163.  
  164. def adjacent(self, state: State):
  165. """
  166. Returns the adjacent STATES to a state
  167. """
  168. x, y = self._get_idx(state.index)
  169. idxs = ((x+i,y+j) for i in range(-1,2) for j in range(-1,2))
  170. idxs = list(self._idx_dict[i] for i in idxs if i in self._idx_dict and i != (x,y))
  171.  
  172. return idxs
  173.  
  174. def is_enemy(self, state):
  175. idx = state.index
  176. return self._enemies
  177.  
  178. def is_goal(self, state):
  179. return False
  180.  
  181. def solve(self):
  182. res = self._algorithm.transverse(self)
  183. return self._get_output(res.states)
  184.  
  185. ####
  186. def _get_output(self, enemies):
  187. indices = self._get_indices(enemies)
  188. m = self._mat.copy()
  189. m[indices] = 'O' # placeholder
  190. m[m == '.'] = 'X'
  191. m[m == 'O'] = '.'
  192. return pretty_matrix(m)
  193.  
  194. def _get_idx(self, enemy):
  195. return tuple(self._enemies[enemy])
  196.  
  197. def _get_indices(self, enemies):
  198. return tuple(zip(*self._enemies[enemies]))
  199.  
  200.  
  201. def _get_border_enemies(self):
  202. n,m = self._mat.shape
  203. l, r = self._enemies[:,0], self._enemies[:,1]
  204. return np.where((l == 0) | (r == 0) | (l == n-1) | (r == m-1))[0]
  205.  
  206. def _in_border(self, enemy_idx):
  207. x, y = self._enemies[enemy_idx,:]
  208. n, m = self._mat.shape
  209. return x == 0 or y == 0 or x == n-1 or y == m-1
  210.  
  211. def __contains__(self, idx):
  212. return idx in self._idx_dict
Add Comment
Please, Sign In to add comment