SHARE
TWEET

Untitled

a guest May 22nd, 2019 69 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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]
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top