Advertisement
Guest User

AI_Lab_1

a guest
Mar 21st, 2018
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 34.51 KB | None | 0 0
  1. import sys
  2. import bisect
  3.  
  4. infinity = float('inf')
  5.  
  6. class Queue:
  7. """Queue is an abstract class/interface. There are three types:
  8. Stack(): A Last In First Out Queue.
  9. FIFOQueue(): A First In First Out Queue.
  10. PriorityQueue(order, f): Queue in sorted order (default min-first).
  11. Each type supports the following methods and functions:
  12. q.append(item) -- add an item to the queue
  13. q.extend(items) -- equivalent to: for item in items: q.append(item)
  14. q.pop() -- return the top item from the queue
  15. len(q) -- number of items in q (also q.__len())
  16. item in q -- does q contain item?
  17. Note that isinstance(Stack(), Queue) is false, because we implement stacks
  18. as lists. If Python ever gets interfaces, Queue will be an interface."""
  19.  
  20. def __init__(self):
  21. raise NotImplementedError
  22.  
  23. def extend(self, items):
  24. for item in items:
  25. self.append(item)
  26.  
  27. class FIFOQueue(Queue):
  28. """A First-In-First-Out Queue."""
  29.  
  30. def __init__(self):
  31. self.A = []
  32. self.start = 0
  33.  
  34. def append(self, item):
  35. self.A.append(item)
  36.  
  37. def __len__(self):
  38. return len(self.A) - self.start
  39.  
  40. def extend(self, items):
  41. self.A.extend(items)
  42.  
  43. def pop(self):
  44. e = self.A[self.start]
  45. self.start += 1
  46. if self.start > 5 and self.start > len(self.A) / 2:
  47. self.A = self.A[self.start:]
  48. self.start = 0
  49. return e
  50.  
  51. def __contains__(self, item):
  52. return item in self.A[self.start:]
  53.  
  54. class Problem:
  55. """The abstract class for a formal problem. You should subclass this and
  56. implement the method successor, and possibly __init__, goal_test, and
  57. path_cost. Then you will create instances of your subclass and solve them
  58. with the various search functions."""
  59.  
  60. def __init__(self, initial, goal=None):
  61. """The constructor specifies the initial state, and possibly a goal
  62. state, if there is a unique goal. Your subclass's constructor can add
  63. other arguments."""
  64. self.initial = initial
  65. self.goal = goal
  66.  
  67. def successor(self, state):
  68. """Given a state, return a dictionary of {action : state} pairs reachable
  69. from this state. If there are many successors, consider an iterator
  70. that yields the successors one at a time, rather than building them
  71. all at once. Iterators will work fine within the framework. Yielding is not supported in Python 2.7"""
  72. raise NotImplementedError
  73.  
  74. def actions(self, state):
  75. """Given a state, return a list of all actions possible from that state"""
  76. raise NotImplementedError
  77.  
  78. def result(self, state, action):
  79. """Given a state and action, return the resulting state"""
  80. raise NotImplementedError
  81.  
  82. def goal_test(self, state):
  83. """Return True if the state is a goal. The default method compares the
  84. state to self.goal, as specified in the constructor. Implement this
  85. method if checking against a single self.goal is not enough."""
  86. return state == self.goal
  87.  
  88. def path_cost(self, c, state1, action, state2):
  89. """Return the cost of a solution path that arrives at state2 from
  90. state1 via action, assuming cost c to get up to state1. If the problem
  91. is such that the path doesn't matter, this function will only look at
  92. state2. If the path does matter, it will consider c and maybe state1
  93. and action. The default method costs 1 for every step in the path."""
  94. return c + 1
  95.  
  96. def value(self):
  97. """For optimization problems, each state has a value. Hill-climbing
  98. and related algorithms try to maximize this value."""
  99. raise NotImplementedError
  100.  
  101. class Node:
  102. """A node in a search tree. Contains a pointer to the parent (the node
  103. that this is a successor of) and to the actual state for this node. Note
  104. that if a state is arrived at by two paths, then there are two nodes with
  105. the same state. Also includes the action that got us to this state, and
  106. the total path_cost (also known as g) to reach the node. Other functions
  107. may add an f and h value; see best_first_graph_search and astar_search for
  108. an explanation of how the f and h values are handled. You will not need to
  109. subclass this class."""
  110.  
  111. def __init__(self, state, parent=None, action=None, path_cost=0):
  112. "Create a search tree Node, derived from a parent by an action."
  113. self.state = state
  114. self.parent = parent
  115. self.action = action
  116. self.path_cost = path_cost
  117. self.depth = 0
  118. if parent:
  119. self.depth = parent.depth + 1
  120.  
  121. def __repr__(self):
  122. return "<Node %s>" % (self.state,)
  123.  
  124. def __lt__(self, node):
  125. return self.state < node.state
  126.  
  127. def expand(self, problem):
  128. "List the nodes reachable in one step from this node."
  129. return [self.child_node(problem, action)
  130. for action in problem.actions(self.state)]
  131.  
  132. def child_node(self, problem, action):
  133. "Return a child node from this node"
  134. next = problem.result(self.state, action)
  135. return Node(next, self, action,
  136. problem.path_cost(self.path_cost, self.state,
  137. action, next))
  138.  
  139. def solution(self):
  140. "Return the sequence of actions to go from the root to this node."
  141. return [node.action for node in self.path()[1:]]
  142.  
  143. def solve(self):
  144. "Return the sequence of states to go from the root to this node."
  145. return [node.state for node in self.path()[0:]]
  146.  
  147. def path(self):
  148. "Return a list of nodes forming the path from the root to this node."
  149. x, result = self, []
  150. while x:
  151. result.append(x)
  152. x = x.parent
  153. return list(reversed(result))
  154.  
  155. # We want for a queue of nodes in breadth_first_search or
  156. # astar_search to have no duplicated states, so we treat nodes
  157. # with the same state as equal. [Problem: this may not be what you
  158. # want in other contexts.]
  159.  
  160. def __eq__(self, other):
  161. return isinstance(other, Node) and self.state == other.state
  162.  
  163. def __hash__(self):
  164. return hash(self.state)
  165.  
  166. def graph_search(problem, fringe):
  167. """Search through the successors of a problem to find a goal.
  168. The argument fringe should be an empty queue.
  169. If two paths reach a state, only use the best one."""
  170. closed = {}
  171. fringe.append(Node(problem.initial))
  172. while fringe:
  173. node = fringe.pop()
  174. if problem.goal_test(node.state):
  175. return node
  176. if node.state not in closed:
  177. closed[node.state] = True
  178. fringe.extend(node.expand(problem))
  179. return None
  180.  
  181. def breadth_first_graph_search(problem):
  182. "Search the shallowest nodes in the search tree first."
  183. return graph_search(problem, FIFOQueue())
  184.  
  185.  
  186.  
  187. #koordinati na site prepreki vo shemata
  188. Obstacles = [(1,4),(1,6),(1,8),(2,3),(2,9),
  189. (4,2),(4,7),(4,8),(5,5),(5,7),
  190. (6,1),(6,2),(6,4),(6,7)]
  191.  
  192. #sostojba na nekoj atom ja definiram kako koordinati na site ostali atomi na primer H1x,H2x,Ox,Oy,H2x,H2y
  193. def upAtomH1(A):
  194. tuple = ((A[2],A[3]),(A[4],A[5]))
  195. while(A[0] > 0 and A[0] < 8 and A[1]> 0 and A[1]< 10 and #proveruvam dali mi iskacha od tablata
  196. ((A[0],A[1]) not in Obstacles) and #check wether i have landed on an obstacle
  197. ((A[0],A[1]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  198. X=A[0] #the x coordinate of the atom is placed in the variable x
  199. X=X-1 #i reduce the x value because that is what happens when i move up in my coordinate system
  200. A=(X,A[1],A[2],A[3],A[4],A[5]) #vo A ja smestuvam novata sostojba na atomot so smeneta x coordinate
  201.  
  202. Anew=(A[0]+1,A[1]) #vo Anew stavam koordinati, po izvrshuvanje na while. za da zavrshi while moralo da stignam negde kaj sho ne e okej
  203. #zatoa mi sluzhi toa +1 za da se vratam edna poz nazad pred da napraam sranja za da iskocam od while
  204. #whileot ustvari e za neprekinato pushing vo edna nasoka
  205. return Anew
  206.  
  207. def downAtomH1(A):
  208. tuple = ((A[2],A[3]),(A[4],A[5]))
  209. while(A[0] > 0 and A[0] < 8 and A[1]> 0 and A[1]< 10 and #proveruvam dali mi iskacha od tablata
  210. ((A[0],A[1]) not in Obstacles) and #check wether i have landed on an obstacle
  211. ((A[0],A[1]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  212. X=A[0] #the x coordinate of the atom is placed in the variable x
  213. X=X+1 #i reduce the x value because that is what happens when i move up in my coordinate system
  214. A=(X,A[1],A[2],A[3],A[4],A[5]) #vo A ja smestuvam novata sostojba na atomot so smeneta x coordinate
  215.  
  216. Anew=(A[0]-1,A[1]) #vo Anew stavam koordinati, po izvrshuvanje na while. za da zavrshi while moralo da stignam negde kaj sho ne e okej
  217. #zatoa mi sluzhi toa +1 za da se vratam edna poz nazad pred da napraam sranja za da iskocam od while
  218. #whileot ustvari e za neprekinato pushing vo edna nasoka
  219. return Anew
  220.  
  221. def leftAtomH1(A):
  222. tuple = ((A[2],A[3]),(A[4],A[5]))
  223. while(A[0] > 0 and A[0] < 8 and A[1]> 0 and A[1]< 10 and #proveruvam dali mi iskacha od tablata
  224. ((A[0],A[1]) not in Obstacles) and #check wether i have landed on an obstacle
  225. ((A[0],A[1]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  226. Y=A[1] #the x coordinate of the atom is placed in the variable x
  227. Y=Y-1 #i reduce the x value because that is what happens when i move up in my coordinate system
  228. A=(A[0],Y,A[2],A[3],A[4],A[5]) #vo A ja smestuvam novata sostojba na atomot so smeneta x coordinate
  229.  
  230. Anew=(A[0],A[1]+1) #vo Anew stavam koordinati, po izvrshuvanje na while. za da zavrshi while moralo da stignam negde kaj sho ne e okej
  231. #zatoa mi sluzhi toa +1 za da se vratam edna poz nazad pred da napraam sranja za da iskocam od while
  232. #whileot ustvari e za neprekinato pushing vo edna nasoka
  233. return Anew
  234.  
  235. def rightAtomH1(A):
  236. tuple = ((A[2],A[3]),(A[4],A[5]))
  237. while(A[0] > 0 and A[0] < 8 and A[1]> 0 and A[1]< 10 and #proveruvam dali mi iskacha od tablata
  238. ((A[0],A[1]) not in Obstacles) and #check wether i have landed on an obstacle
  239. ((A[0],A[1]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  240. Y = A[1] # the x coordinate of the atom is placed in the variable x
  241. Y = Y + 1 # i reduce the x value because that is what happens when i move up in my coordinate system
  242. A = (A[0], Y, A[2], A[3], A[4], A[5]) # vo A ja smestuvam novata sostojba na atomot so smeneta x coordinate
  243.  
  244. Anew = (A[0], A[1] - 1) #vo Anew stavam koordinati, po izvrshuvanje na while. za da zavrshi while moralo da stignam negde kaj sho ne e okej
  245. #zatoa mi sluzhi toa +1 za da se vratam edna poz nazad pred da napraam sranja za da iskocam od while
  246. #whileot ustvari e za neprekinato pushing vo edna nasoka
  247. return Anew
  248.  
  249. def upAtomO(A):
  250. tuple = ((A[0], A[1]), (A[4], A[5]))
  251. while (A[2] > 0 and A[2] < 8 and A[3] > 0 and A[3] < 10 and # proveruvam dali mi iskacha od tablata
  252. ((A[2], A[3]) not in Obstacles) and # check wether i have landed on an obstacle
  253. ((A[2], A[3]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  254. X=A[3]
  255. X=X-1
  256. A=(A[0],A[1],X,A[3],A[4],A[5])
  257. Anew=(A[2]+1,A[3])
  258. return Anew
  259.  
  260. def upAtomO(A):
  261. tuple = ((A[0], A[1]), (A[4], A[5]))
  262. while (A[2] > 0 and A[2] < 8 and A[3] > 0 and A[3] < 10 and # proveruvam dali mi iskacha od tablata
  263. ((A[2], A[3]) not in Obstacles) and # check wether i have landed on an obstacle
  264. ((A[2], A[3]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  265. X=A[3]
  266. X=X-1
  267. A=(A[0],A[1],X,A[3],A[4],A[5])
  268. Anew=(A[2]+1,A[3])
  269. return Anew
  270.  
  271. def downAtomO(A):
  272. tuple = ((A[0], A[1]), (A[4], A[5]))
  273. while (A[2] > 0 and A[2] < 8 and A[3] > 0 and A[3] < 10 and # proveruvam dali mi iskacha od tablata
  274. ((A[2], A[3]) not in Obstacles) and # check wether i have landed on an obstacle
  275. ((A[2], A[3]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  276. X=A[3]
  277. X=X+1
  278. A=(A[0],A[1],X,A[3],A[4],A[5])
  279. Anew=(A[2]-1,A[3])
  280. return Anew
  281.  
  282. def leftAtomO(A):
  283. tuple = ((A[0], A[1]), (A[4], A[5]))
  284. while (A[2] > 0 and A[2] < 8 and A[3] > 0 and A[3] < 10 and # proveruvam dali mi iskacha od tablata
  285. ((A[2], A[3]) not in Obstacles) and # check wether i have landed on an obstacle
  286. ((A[2], A[3]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  287. Y=A[3]
  288. Y=Y-1
  289. A=(A[0],A[1],A[2],Y,A[4],A[5])
  290. Anew=(A[2],A[3]+1)
  291. return Anew
  292.  
  293. def rightAtomO(A):
  294. tuple = ((A[0], A[1]), (A[4], A[5]))
  295. while (A[2] > 0 and A[2] < 8 and A[3] > 0 and A[3] < 10 and # proveruvam dali mi iskacha od tablata
  296. ((A[2], A[3]) not in Obstacles) and # check wether i have landed on an obstacle
  297. ((A[2], A[3]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  298. Y=A[3]
  299. Y=Y+1
  300. A=(A[0],A[1],A[2],Y,A[4],A[5])
  301. Anew=(A[2],A[3]-1)
  302. return Anew
  303.  
  304. def upAtomH2(A):
  305. tuple = ((A[2],A[3]),(A[4],A[5]))
  306. while(A[0] > 0 and A[0] < 8 and A[1]> 0 and A[1]< 10 and #proveruvam dali mi iskacha od tablata
  307. ((A[0],A[1]) not in Obstacles) and #check wether i have landed on an obstacle
  308. ((A[0],A[1]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  309. X=A[0] #the x coordinate of the atom is placed in the variable x
  310. X=X-1 #i reduce the x value because that is what happens when i move up in my coordinate system
  311. A=(X,A[1],A[2],A[3],A[4],A[5]) #vo A ja smestuvam novata sostojba na atomot so smeneta x coordinate
  312.  
  313. Anew=(A[0]+1,A[1]) #vo Anew stavam koordinati, po izvrshuvanje na while. za da zavrshi while moralo da stignam negde kaj sho ne e okej
  314. #zatoa mi sluzhi toa +1 za da se vratam edna poz nazad pred da napraam sranja za da iskocam od while
  315. #whileot ustvari e za neprekinato pushing vo edna nasoka
  316. return Anew
  317.  
  318. def downAtomH2(A):
  319. tuple = ((A[2],A[3]),(A[4],A[5]))
  320. while(A[0] > 0 and A[0] < 8 and A[1]> 0 and A[1]< 10 and #proveruvam dali mi iskacha od tablata
  321. ((A[0],A[1]) not in Obstacles) and #check wether i have landed on an obstacle
  322. ((A[0],A[1]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  323. X=A[0] #the x coordinate of the atom is placed in the variable x
  324. X=X+1 #i reduce the x value because that is what happens when i move up in my coordinate system
  325. A=(X,A[1],A[2],A[3],A[4],A[5]) #vo A ja smestuvam novata sostojba na atomot so smeneta x coordinate
  326.  
  327. Anew=(A[0]-1,A[1]) #vo Anew stavam koordinati, po izvrshuvanje na while. za da zavrshi while moralo da stignam negde kaj sho ne e okej
  328. #zatoa mi sluzhi toa +1 za da se vratam edna poz nazad pred da napraam sranja za da iskocam od while
  329. #whileot ustvari e za neprekinato pushing vo edna nasoka
  330. return Anew
  331.  
  332. def leftAtomH2(A):
  333. tuple = ((A[2],A[3]),(A[4],A[5]))
  334. while(A[0] > 0 and A[0] < 8 and A[1]> 0 and A[1]< 10 and #proveruvam dali mi iskacha od tablata
  335. ((A[0],A[1]) not in Obstacles) and #check wether i have landed on an obstacle
  336. ((A[0],A[1]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  337. Y=A[1] #the x coordinate of the atom is placed in the variable x
  338. Y=Y-1 #i reduce the x value because that is what happens when i move up in my coordinate system
  339. A=(A[0],Y,A[2],A[3],A[4],A[5]) #vo A ja smestuvam novata sostojba na atomot so smeneta x coordinate
  340.  
  341. Anew=(A[0],A[1]+1) #vo Anew stavam koordinati, po izvrshuvanje na while. za da zavrshi while moralo da stignam negde kaj sho ne e okej
  342. #zatoa mi sluzhi toa +1 za da se vratam edna poz nazad pred da napraam sranja za da iskocam od while
  343. #whileot ustvari e za neprekinato pushing vo edna nasoka
  344. return Anew
  345.  
  346. def rightAtomH2(A):
  347. tuple = ((A[2],A[3]),(A[4],A[5]))
  348. while(A[0] > 0 and A[0] < 8 and A[1]> 0 and A[1]< 10 and #proveruvam dali mi iskacha od tablata
  349. ((A[0],A[1]) not in Obstacles) and #check wether i have landed on an obstacle
  350. ((A[0],A[1]) not in tuple)): # check wether i am in the same position as the other 2 atoms
  351. Y = A[1] # the x coordinate of the atom is placed in the variable x
  352. Y = Y + 1 # i reduce the x value because that is what happens when i move up in my coordinate system
  353. A = (A[0], Y, A[2], A[3], A[4], A[5]) # vo A ja smestuvam novata sostojba na atomot so smeneta x coordinate
  354.  
  355. Anew = (A[0], A[1] - 1) #vo Anew stavam koordinati, po izvrshuvanje na while. za da zavrshi while moralo da stignam negde kaj sho ne e okej
  356. #zatoa mi sluzhi toa +1 za da se vratam edna poz nazad pred da napraam sranja za da iskocam od while
  357. #whileot ustvari e za neprekinato pushing vo edna nasoka
  358. return Anew
  359.  
  360. class Molekula(Problem):
  361.  
  362. def __init__(self,initial):
  363. self.initial=initial
  364.  
  365. def goal_test(self,state):
  366. H1X = state[0]
  367. H1Y = state[1]
  368. OX = state[2]
  369. OY = state[3]
  370. H2X = state[4]
  371. H2Y = state[5]
  372. return(H1X == OX and OX == H2X and #proverka dali H1 i O se vo ista kolona posho za da se edni do drugi mora da se u ista kolona
  373. OY == H1Y +1 and #proverka dali i drugiot H2 atom e vo ista redica so ovie
  374. H2Y == OY+1) #dali se bash edni do drugi so rastojanie 0 megju sebe na sosedni kvadrati
  375.  
  376. def successor(self,state):
  377. successors=dict() #definiram prazen rechnik
  378. H1 = state[0],state[1] #vo H1 stavam koordinati na H1 atomot shto gi dobivam od state
  379. O = state[2], state[3] # vo HO stavam koordinati na H1 atomot shto gi dobivam od state
  380. H2 = state[4], state[5] # vo H2 stavam koordinati na H1 atomot shto gi dobivam od state
  381. #podoly kako keyes vo dictionary gi staam iminjata na akciite a kako values gi staam states koi sledat od nekoja takva akcija
  382. #so sekoj nov state koj povikuva nekakva akcija od dict se generiraat novi possible states
  383. #zatoa na pocetokot successors sekogas se definira na prazen rechnik na pochetokot na funkcijava
  384.  
  385. #GI DEFINIRAM SITE MOZHNI POTEZI I NIVNITE REZULTATI ZA H1 ATOM
  386. H1new = upAtomH1(state)
  387. Statenew= (H1new[0], H1new[1], O[0], O[1], H2[0], H2[1])
  388. successors['GoreH1'] = Statenew
  389.  
  390. H1new = downAtomH1(state)
  391. Statenew = (H1new[0], H1new[1], O[0], O[1], H2[0], H2[1])
  392. successors['DoleH1'] = Statenew
  393.  
  394. H1new = leftAtomH1(state)
  395. Statenew = (H1new[0], H1new[1], O[0], O[1], H2[0], H2[1])
  396. successors['LevoH1'] = Statenew
  397.  
  398. H1new = rightAtomH1(state)
  399. Statenew = (H1new[0], H1new[1], O[0], O[1], H2[0], H2[1])
  400. successors['DesnoH1'] = Statenew
  401.  
  402. # GI DEFINIRAM SITE MOZHNI POTEZI I NIVNITE REZULTATI ZA H2 ATOM
  403. H2new = upAtomH2(state)
  404. Statenew = (H1[0],H1[1], O[0], O[1],H2new[0], H2new[1])
  405. successors['GoreH2'] = Statenew
  406.  
  407. H2new = downAtomH2(state)
  408. Statenew = (H1[0],H1[1], O[0], O[1],H2new[0], H2new[1])
  409. successors['DoleH2'] = Statenew
  410.  
  411. H2new = leftAtomH2(state)
  412. Statenew = (H1[0],H1[1], O[0], O[1],H2new[0], H2new[1])
  413. successors['LevoH2'] = Statenew
  414.  
  415. H2new = rightAtomH2(state)
  416. Statenew = (H1[0],H1[1], O[0], O[1],H2new[0], H2new[1])
  417. successors['DesnoH2'] = Statenew
  418.  
  419. # GI DEFINIRAM SITE MOZHNI POTEZI I NIVNITE REZULTATI ZA O ATOM
  420. Onew = upAtomO(state)
  421. Statenew = (H1[0], H1[1], Onew[0], Onew[1], H2[0], H2[1])
  422. successors['GoreO'] = Statenew
  423.  
  424. Onew = downAtomO(state)
  425. Statenew = (H1[0], H1[1], Onew[0], Onew[1], H2[0], H2[1])
  426. successors['DoleO'] = Statenew
  427.  
  428. Onew = leftAtomO(state)
  429. Statenew = (H1[0], H1[1], Onew[0], Onew[1], H2[0], H2[1])
  430. successors['LevoO'] = Statenew
  431.  
  432. Onew = rightAtomO(state)
  433. Statenew = (H1[0], H1[1], Onew[0], Onew[1], H2[0], H2[1])
  434. successors['DesnoO'] = Statenew
  435.  
  436. return successors
  437.  
  438. def actions(self, state):
  439. return self.successor(state).keys() #gi vrakjam site mozhni AKCII
  440.  
  441.  
  442.  
  443. def result(self, state, action):
  444. possible = self.successor(state) #vrakjam koja sostojba e rezultat na dadena akcija pratena kako prarametar
  445. return possible[action]
  446.  
  447.  
  448.  
  449. #Vcituvanje na vleznite argumenti za test primerite
  450. H1AtomRedica = int(input()) #atomot so link desno
  451. H1AtomKolona = int(input())
  452. OAtomRedica = int(input())
  453. OAtomKolona = int(input())
  454. H2AtomRedica = int(input()) #atomot so link levo
  455. H2AtomKolona = int(input())
  456.  
  457. #Vasiot kod pisuvajte go pod ovoj komentar
  458.  
  459. MolekulaInstance = Molekula((H1AtomRedica, H1AtomKolona, OAtomRedica, OAtomKolona, H2AtomRedica, H2AtomKolona))
  460.  
  461. answer = breadth_first_graph_search(MolekulaInstance)
  462. print (answer.solution())
  463.  
  464.  
  465.  
  466.  
  467.  
  468. import sys
  469. import bisect
  470.  
  471. infinity = float('inf')
  472.  
  473. class Queue:
  474. """Queue is an abstract class/interface. There are three types:
  475. Stack(): A Last In First Out Queue.
  476. FIFOQueue(): A First In First Out Queue.
  477. PriorityQueue(order, f): Queue in sorted order (default min-first).
  478. Each type supports the following methods and functions:
  479. q.append(item) -- add an item to the queue
  480. q.extend(items) -- equivalent to: for item in items: q.append(item)
  481. q.pop() -- return the top item from the queue
  482. len(q) -- number of items in q (also q.__len())
  483. item in q -- does q contain item?
  484. Note that isinstance(Stack(), Queue) is false, because we implement stacks
  485. as lists. If Python ever gets interfaces, Queue will be an interface."""
  486.  
  487. def __init__(self):
  488. raise NotImplementedError
  489.  
  490. def extend(self, items):
  491. for item in items:
  492. self.append(item)
  493.  
  494. class FIFOQueue(Queue):
  495. """A First-In-First-Out Queue."""
  496.  
  497. def __init__(self):
  498. self.A = []
  499. self.start = 0
  500.  
  501. def append(self, item):
  502. self.A.append(item)
  503.  
  504. def __len__(self):
  505. return len(self.A) - self.start
  506.  
  507. def extend(self, items):
  508. self.A.extend(items)
  509.  
  510. def pop(self):
  511. e = self.A[self.start]
  512. self.start += 1
  513. if self.start > 5 and self.start > len(self.A) / 2:
  514. self.A = self.A[self.start:]
  515. self.start = 0
  516. return e
  517.  
  518. def __contains__(self, item):
  519. return item in self.A[self.start:]
  520.  
  521. class Problem:
  522. """The abstract class for a formal problem. You should subclass this and
  523. implement the method successor, and possibly __init__, goal_test, and
  524. path_cost. Then you will create instances of your subclass and solve them
  525. with the various search functions."""
  526.  
  527. def __init__(self, initial, goal=None):
  528. """The constructor specifies the initial state, and possibly a goal
  529. state, if there is a unique goal. Your subclass's constructor can add
  530. other arguments."""
  531. self.initial = initial
  532. self.goal = goal
  533.  
  534. def successor(self, state):
  535. """Given a state, return a dictionary of {action : state} pairs reachable
  536. from this state. If there are many successors, consider an iterator
  537. that yields the successors one at a time, rather than building them
  538. all at once. Iterators will work fine within the framework. Yielding is not supported in Python 2.7"""
  539. raise NotImplementedError
  540.  
  541. def actions(self, state):
  542. """Given a state, return a list of all actions possible from that state"""
  543. raise NotImplementedError
  544.  
  545. def result(self, state, action):
  546. """Given a state and action, return the resulting state"""
  547. raise NotImplementedError
  548.  
  549. def goal_test(self, state):
  550. """Return True if the state is a goal. The default method compares the
  551. state to self.goal, as specified in the constructor. Implement this
  552. method if checking against a single self.goal is not enough."""
  553. return state == self.goal
  554.  
  555. def path_cost(self, c, state1, action, state2):
  556. """Return the cost of a solution path that arrives at state2 from
  557. state1 via action, assuming cost c to get up to state1. If the problem
  558. is such that the path doesn't matter, this function will only look at
  559. state2. If the path does matter, it will consider c and maybe state1
  560. and action. The default method costs 1 for every step in the path."""
  561. return c + 1
  562.  
  563. def value(self):
  564. """For optimization problems, each state has a value. Hill-climbing
  565. and related algorithms try to maximize this value."""
  566. raise NotImplementedError
  567.  
  568. class Node:
  569. """A node in a search tree. Contains a pointer to the parent (the node
  570. that this is a successor of) and to the actual state for this node. Note
  571. that if a state is arrived at by two paths, then there are two nodes with
  572. the same state. Also includes the action that got us to this state, and
  573. the total path_cost (also known as g) to reach the node. Other functions
  574. may add an f and h value; see best_first_graph_search and astar_search for
  575. an explanation of how the f and h values are handled. You will not need to
  576. subclass this class."""
  577.  
  578. def __init__(self, state, parent=None, action=None, path_cost=0):
  579. "Create a search tree Node, derived from a parent by an action."
  580. self.state = state
  581. self.parent = parent
  582. self.action = action
  583. self.path_cost = path_cost
  584. self.depth = 0
  585. if parent:
  586. self.depth = parent.depth + 1
  587.  
  588. def __repr__(self):
  589. return "<Node %s>" % (self.state,)
  590.  
  591. def __lt__(self, node):
  592. return self.state < node.state
  593.  
  594. def expand(self, problem):
  595. "List the nodes reachable in one step from this node."
  596. return [self.child_node(problem, action)
  597. for action in problem.actions(self.state)]
  598.  
  599. def child_node(self, problem, action):
  600. "Return a child node from this node"
  601. next = problem.result(self.state, action)
  602. return Node(next, self, action,
  603. problem.path_cost(self.path_cost, self.state,
  604. action, next))
  605.  
  606. def solution(self):
  607. "Return the sequence of actions to go from the root to this node."
  608. return [node.action for node in self.path()[1:]]
  609.  
  610. def solve(self):
  611. "Return the sequence of states to go from the root to this node."
  612. return [node.state for node in self.path()[0:]]
  613.  
  614. def path(self):
  615. "Return a list of nodes forming the path from the root to this node."
  616. x, result = self, []
  617. while x:
  618. result.append(x)
  619. x = x.parent
  620. return list(reversed(result))
  621.  
  622. # We want for a queue of nodes in breadth_first_search or
  623. # astar_search to have no duplicated states, so we treat nodes
  624. # with the same state as equal. [Problem: this may not be what you
  625. # want in other contexts.]
  626.  
  627. def __eq__(self, other):
  628. return isinstance(other, Node) and self.state == other.state
  629.  
  630. def __hash__(self):
  631. return hash(self.state)
  632.  
  633. def graph_search(problem, fringe):
  634. """Search through the successors of a problem to find a goal.
  635. The argument fringe should be an empty queue.
  636. If two paths reach a state, only use the best one."""
  637. closed = {}
  638. fringe.append(Node(problem.initial))
  639. while fringe:
  640. node = fringe.pop()
  641. if problem.goal_test(node.state):
  642. return node
  643. if node.state not in closed:
  644. closed[node.state] = True
  645. fringe.extend(node.expand(problem))
  646. return None
  647.  
  648. def breadth_first_graph_search(problem):
  649. "Search the shallowest nodes in the search tree first."
  650. return graph_search(problem, FIFOQueue())
  651.  
  652.  
  653.  
  654.  
  655.  
  656. def updateP1(P): #horisontal, to the left, start state: 2,2 and 2,3
  657. (X,Y,Nasoka) = P
  658. if(Y == 0 and Nasoka == 1) or (Y == 4 and Nasoka == -1): #ako sum doshla do nekoj od dzidovite sho me ogranichuvaat menjam nasoka
  659. Nasoka = Nasoka * (-1)
  660. Ynew = Y - Nasoka #na X mu se dodava/ odzema eden chekor zavisno od nasokata
  661. Pnew = (X, Ynew, Nasoka)
  662. return Pnew
  663.  
  664. def updateP2(P): #diagonal, upward right, start state: 8,2 8,3 7,2 7,3
  665. (X, Y, Nasoka) = P
  666. if (X == 10 and Nasoka == -1) or (X == 6 and Nasoka == 1): # ako sum doshla do nekoj od dzidovite sho me ogranichuvaat menjam nasoka
  667. Nasoka = Nasoka * (-1)
  668. Xnew = X - Nasoka # na X mu se dodava/ odzema eden chekor zavisno od nasokata
  669. Ynew = Y + Nasoka
  670. Pnew = (Xnew, Ynew, Nasoka)
  671. return Pnew
  672.  
  673. def updateP3(P): #vertical, down, 8,8 9,8
  674. (X,Y,Nasoka) = P
  675. if(X == 10 and Nasoka == 1) or (X == 6 and Nasoka == -1): #ako sum doshla do nekoj od dzidovite sho me ogranichuvaat menjam nasoka
  676. Nasoka = Nasoka * (-1)
  677. Xnew = X + Nasoka #na X mu se dodava/ odzema eden chekor zavisno od nasokata
  678. Pnew = (Xnew, Y, Nasoka)
  679. return Pnew
  680.  
  681. class Istrazuvac(Problem):
  682.  
  683. def __init__(self, initial, goal):
  684. self.initial = initial
  685. self.goal = goal
  686. def goal_test(self, state):
  687. g = self.goal
  688. return (state [0] == g[0] and state[1] == g[1])
  689.  
  690. def successor(self,state):
  691. successors = dict()
  692.  
  693. X = state[0]
  694. Y = state[1]
  695. P1 = (state[2], state[3], state[4])
  696. P2 = (state[5], state[6], state[7])
  697. P3 = (state[8], state[9], state[10])
  698.  
  699. #ako x e pomalo od 10 mozam da odam nadolu
  700. if(X < 10):
  701. Xnew = X + 1
  702. Ynew = Y
  703. P1new = updateP1(P1)
  704. P2new = updateP2(P2)
  705. P3new = updateP3(P3)
  706. #obstacles se site koordinati kade bi se nashle preckite vo slednata iteracija
  707. obstacles = (P1new[0], P1new[1]), (P1new[0], P1new[1]+1), (P2new[0], P2new[1]), (P2new[0]-1, P2new[1]), (P2new[0], P2new[1]+1), (P2new[0]-1, P2new[1]+1), (P3new[0], P3new[1]), (P3new[0]+1, P3new[1])
  708. if( (Xnew, Ynew) not in obstacles):
  709. Statenew = (Xnew, Ynew, P1new[0], P1new[1], P1new[2], P2new[0],P2new[1], P2new[2],P3new[0], P3new[1], P3new[2])
  710. #vo statenew mi e novoto stanje posle mrdanje dole ako pomine ifot odnosno ovaa promena na sostojba nastanuva samo ako site constraints se zadovoleni
  711. successors['Dolu'] = Statenew
  712.  
  713. #ako x e pogolemo od 0 mozham da odam nagore
  714. if (X > 0):
  715. Xnew = X - 1
  716. Ynew = Y
  717. P1new = updateP1(P1)
  718. P2new = updateP2(P2)
  719. P3new = updateP3(P3)
  720. # obstacles se site koordinati kade bi se nashle preckite vo slednata iteracija
  721. obstacles = (P1new[0], P1new[1]), (P1new[0], P1new[1] + 1), (P2new[0], P2new[1]), (P2new[0] - 1, P2new[1]), (P2new[0], P2new[1] + 1), (P2new[0] - 1, P2new[1] + 1), (P3new[0], P3new[1]), (P3new[0] + 1, P3new[1])
  722. if (((Xnew, Ynew) not in obstacles) and ((Y < 5) or (X > 5))):
  723. Statenew = (
  724. Xnew, Ynew, P1new[0], P1new[1], P1new[2], P2new[0], P2new[1], P2new[2], P3new[0], P3new[1], P3new[2])
  725. # vo statenew mi e novoto stanje posle mrdanje dole ako pomine ifot odnosno ovaa promena na sostojba nastanuva samo ako site constraints se zadovoleni
  726. successors['Gore'] = Statenew
  727.  
  728. #ako y>0 mozham da odam vo levo
  729. if (Y > 0):
  730. Xnew = X
  731. Ynew = Y - 1
  732. P1new = updateP1(P1)
  733. P2new = updateP2(P2)
  734. P3new = updateP3(P3)
  735. # obstacles se site koordinati kade bi se nashle preckite vo slednata iteracija
  736. obstacles = (P1new[0], P1new[1]), (P1new[0], P1new[1] + 1), (P2new[0], P2new[1]), (P2new[0] - 1, P2new[1]), (P2new[0], P2new[1] + 1), (P2new[0] - 1, P2new[1] + 1), (P3new[0], P3new[1]), (P3new[0] + 1, P3new[1])
  737. if ((Xnew, Ynew) not in obstacles):
  738. Statenew = (
  739. Xnew, Ynew, P1new[0], P1new[1], P1new[2], P2new[0], P2new[1], P2new[2], P3new[0], P3new[1], P3new[2])
  740. # vo statenew mi e novoto stanje posle mrdanje dole ako pomine ifot odnosno ovaa promena na sostojba nastanuva samo ako site constraints se zadovoleni
  741. successors['Levo'] = Statenew
  742.  
  743. # ako y<10 mozham da odam vo desno
  744. if (Y > 0):
  745. Xnew = X
  746. Ynew = Y + 1
  747. P1new = updateP1(P1)
  748. P2new = updateP2(P2)
  749. P3new = updateP3(P3)
  750. # obstacles se site koordinati kade bi se nashle preckite vo slednata iteracija
  751. obstacles = (P1new[0], P1new[1]), (P1new[0], P1new[1] + 1), (P2new[0], P2new[1]), (
  752. P2new[0] - 1, P2new[1]), (P2new[0], P2new[1] + 1), (P2new[0] - 1, P2new[1] + 1), (
  753. P3new[0], P3new[1]), (P3new[0] + 1, P3new[1])
  754. if (((Xnew, Ynew) not in obstacles) and ((X > 4) or (Y < 5))):
  755. Statenew = (Xnew, Ynew, P1new[0], P1new[1], P1new[2], P2new[0], P2new[1], P2new[2], P3new[0], P3new[1],
  756. P3new[2])
  757. # vo statenew mi e novoto stanje posle mrdanje dole ako pomine ifot odnosno ovaa promena na sostojba nastanuva samo ako site constraints se zadovoleni
  758. successors['Desno'] = Statenew
  759. return successors
  760.  
  761.  
  762. def actions(self,state):
  763. return self.successor(state).keys() #gi vrakjam site mozhni AKCII
  764.  
  765. def result(self,state,action):
  766. possible = self.successor(state) #vrakjam koja sostojba e rezultat na dadena akcija pratena kako prarametar
  767. return possible[action]
  768.  
  769. #Vcituvanje na vleznite argumenti za test primerite
  770.  
  771. CoveceRedica = int(input())
  772. CoveceKolona = int(input())
  773. KukjaRedica = int(input())
  774. KukjaKolona = int(input())
  775.  
  776. #Vasiot kod pisuvajte go pod ovoj komentar
  777.  
  778. K = [KukjaRedica, KukjaKolona]
  779. IstrazuvacInstance = Istrazuvac((CoveceRedica, CoveceKolona,2,1,1,7,3,1,9,8,1),K)
  780.  
  781. answer = breadth_first_graph_search(IstrazuvacInstance)
  782. print (answer.solution())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement