Advertisement
Guest User

Untitled

a guest
May 22nd, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.19 KB | None | 0 0
  1. import numpy as np
  2. import random
  3.  
  4. file = 'input.txt'
  5. generations = 1000
  6.  
  7.  
  8. class world:
  9. __map = {}
  10. __totalGold = 0
  11. __goldPos = []
  12. __golds = []
  13. __collectedGold = 0
  14. __maxX = 0
  15. __maxY = 0
  16. __startX = 0
  17. __startY = 0
  18. __x = 0
  19. __y = 0
  20. __sequence = []
  21.  
  22. def load(self, file):
  23. f = open(file, 'r')
  24. data = f.read().split('\n')
  25. f.close()
  26. self.__parse(data)
  27.  
  28. def __parse(self, data):
  29. y = 0
  30. for line in data:
  31. self.__maxY = y
  32. x = 0
  33. for char in line:
  34. self.__maxX = max(self.__maxX, x)
  35. self.__map[(x,y)] = char
  36. if char == 'g':
  37. self.__totalGold+=1
  38. self.__goldPos.append([x,y])
  39. if char == 's':
  40. self.__startX = x
  41. self.__startY = y
  42. x+=1
  43. y+=1
  44.  
  45. def createpop(self):
  46. indiv = []
  47. for i in range(20):
  48. ind = np.zeros(64)
  49. for n in range(16):
  50. ind[n] = np.random.randint(0,255)
  51. indiv.append(ind)
  52. return indiv
  53.  
  54. def moveagent(self,direction):
  55. self.__sequence.append(direction)
  56. if direction == 'U':
  57. self.__y -= 1
  58. if direction == 'D':
  59. self.__y += 1
  60. if direction == 'R':
  61. self.__x += 1
  62. if direction == 'L':
  63. self.__x -= 1
  64. for gold in self.__golds:
  65. if [self.__x,self.__y] == gold:
  66. self.__collectedGold += 1
  67. self.__golds.remove(gold)
  68.  
  69. def execute(self,virtmach):
  70. self.__golds = self.__goldPos.copy()
  71. self.__collectedGold = 0
  72. self.__x = self.__startX
  73. self.__y = self.__startY
  74. stepout = 0
  75. steps = 0
  76. address = 0
  77. self.__sequence = []
  78.  
  79. while True:
  80. if steps >= 500:
  81. break
  82. if self.__y > self.__maxY or self.__x > self.__maxX or self.__y < 0 or self.__x < 0:
  83. stepout = 1
  84. break
  85. if self.__collectedGold == self.__totalGold:
  86. print ('Success!',self.__sequence)
  87. break
  88.  
  89. val = int(virtmach[address])
  90. if (val >> 6) == 0:
  91. addr = val & 0b00111111
  92. virtmach[addr] = (virtmach[addr] + 1) % 256
  93. address = (address + 1) % 64
  94. elif (val >> 6) == 1:
  95. addr = val & 0b00111111
  96. if virtmach[addr] == 0:
  97. virtmach[addr] = 255
  98. else:
  99. virtmach[addr] -= 1
  100. address = (address + 1) % 64
  101. elif (val >> 6) == 2:
  102. address = val & 0b00111111
  103. elif (val >> 6) == 3:
  104. move = val & 0b00111111
  105. countones = (bin(move).count("1"))+2
  106. if countones <= 2:
  107. self.moveagent('U')
  108. elif countones == 3 or countones == 4:
  109. self.moveagent('D')
  110. elif countones == 5 or countones == 6:
  111. self.moveagent('R')
  112. elif countones >= 7:
  113. self.moveagent('L')
  114. address = (address + 1) % 64
  115. steps += 1
  116. fit = 1 + self.__collectedGold*2 - (steps*0.001) - (stepout*0.01)
  117. return fit
  118.  
  119. def evalfit(self,indiv):
  120. fitarr = np.zeros(len(indiv))
  121. for i in range(len(indiv)):
  122. virtmach = indiv[i].copy()
  123. fitness = self.execute(virtmach)
  124. fitarr[i] = fitness
  125. return fitarr
  126.  
  127. def tournament_selection(self,prevpop,fitvect,k):
  128. p = 0.8
  129. pop = prevpop.copy()
  130. selected = []
  131. elite = []
  132. elitpos = np.argpartition(fitvect,-3)[-3:]
  133. for i in range(len(elitpos)-1):
  134. elite.append(pop[elitpos[i]])
  135.  
  136. for n in range(4):
  137. pos = []
  138. indi = []
  139. for i in range(k):
  140. pos.append(random.randint(0,len(pop)-1))
  141. for n in range(len(pos)):
  142. indi.append(fitvect[pos[n]])
  143.  
  144. prob = np.random.uniform(0,1)
  145. if prob < p:
  146. sel1 = max(indi)
  147. pos1 = np.where(fitvect == sel1)[0][0]
  148. else:
  149. pos1 = random.randint(0,len(pop)-1)
  150. selected.append(pop[pos1])
  151. pop.pop(pos1)
  152. np.delete(fitvect,pos1)
  153.  
  154. return selected,elite
  155.  
  156. def crossover(self,parents,elite):
  157. kids = []
  158. for e in elite:
  159. kids.append(e)
  160. for k in range(20-len(elite)):
  161. shift = random.randint(1,len(parents[0])-2)
  162. m = random.randint(0,len(parents)-1)
  163. d = random.randint(0,len(parents)-1)
  164. while m == d:
  165. d = random.randint(0,len(parents)-1)
  166. kid = parents[m].copy()
  167. kid[0:shift] = parents[d][0:shift]
  168. kids.append(kid)
  169. return kids
  170.  
  171. def mutation(self,pop):
  172. mute = []
  173. num = random.randint(8,len(pop))
  174. for n in range(num):
  175. mute.append(random.randint(0,len(pop)-1))
  176. for m in mute:
  177. indiv = pop[m]
  178. switch1, switch2 = random.randint(0,len(indiv)-1),random.randint(0,len(indiv)-1)
  179. indiv[switch1] += 1
  180. if indiv[switch2] == 0:
  181. indiv[switch2] = 255
  182. else:
  183. indiv[switch2] -= 1
  184. pop[m] = indiv
  185. return pop
  186.  
  187. def newpop(self,prevpop,fitvect):
  188. select = self.tournament_selection(prevpop,fitvect,6)
  189. parents = select[0]
  190. elite = select[1]
  191. newgen = self.crossover(parents,elite)
  192. new = self.mutation(newgen)
  193. return new,self.__collectedGold
  194.  
  195. w = world()
  196. w.load(file)
  197. population = w.createpop()
  198. for g in range(generations):
  199. fitpop = w.evalfit(population)
  200. newp = w.newpop(population,fitpop)
  201. population = newp[0]
  202. collected = newp[1]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement