atulshanbhag

ant_fsm.py

Jun 17th, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.17 KB | None | 0 0
  1. import numpy as np
  2. from scipy.spatial import KDTree
  3. import pygame
  4. from pygame.locals import *
  5. from copy import deepcopy
  6.  
  7. np.random.seed(20)
  8.  
  9. STATES = 12
  10. POP = 100
  11. MOV_LIM = 500
  12. GEN = 200
  13.  
  14.  
  15. SCREEN_SIZE = (417, 417)
  16. BLOCKS = 32
  17. SIZE = 12
  18. MARGIN = 1
  19. FOOD = 80
  20.  
  21.  
  22. WHITE = 0xffffff
  23. BLACK = 0x000000
  24. RED = 0xff0000
  25. GREEN = 0x00ff00
  26. BLUE = 0x0000ff
  27. YELLOW = 0xffff00
  28.  
  29. FPS = 60
  30.  
  31.  
  32. def gen_grid():
  33.     global FOOD
  34.     grid = [[WHITE for _ in range(BLOCKS)] for _ in range(BLOCKS)]
  35.     pts = SCREEN_SIZE[0] * np.random.random((BLOCKS, 2))
  36.     tree = KDTree(pts)
  37.     pts = list(tree.sparse_distance_matrix(tree, FOOD).keys())
  38.     FOOD = len(pts)
  39.     for x, y in pts:
  40.         grid[x][y] = GREEN
  41.     return grid
  42.  
  43.  
  44. def gen_pop():
  45.     pop = []
  46.     for _ in range(POP):
  47.         fsm = []
  48.         for _ in range(STATES):
  49.             state = []
  50.             for i in range(4):
  51.                 if i % 2 == 0:
  52.                     x = np.random.randint(3)
  53.                 else:
  54.                     x = np.random.randint(STATES)
  55.                 state.append(x)
  56.             fsm.append(state)
  57.         pop.append(fsm)
  58.     return pop
  59.  
  60.  
  61. grid = gen_grid()
  62. pop = gen_pop()
  63.  
  64.  
  65. LEFT = {(1, 0): (0, -1),
  66.         (0, -1): (-1, 0),
  67.         (-1, 0): (0, 1),
  68.         (0, 1): (1, 0)}
  69. RIGHT = {(1, 0): (0, 1),
  70.          (0, 1): (-1, 0),
  71.          (-1, 0): (0, -1),
  72.          (0, -1): (1, 0)}
  73.  
  74.  
  75. def cost(pop, p=0):
  76.     costs = []
  77.  
  78.     for i in range(POP):
  79.         vis = {(i, j): False for i in range(BLOCKS) for j in range(BLOCKS)}
  80.         fsm = pop[i]
  81.         state = 0
  82.         eat = 0
  83.         row, col = BLOCKS - 1, 0
  84.         d = (1, 0)
  85.         for g in range(MOV_LIM):
  86.             if grid[row][col] == GREEN and not vis[(row, col)]:
  87.                 eat += 1
  88.                 vis[(row, col)] = True
  89.                 if eat == FOOD:
  90.                     break
  91.             x, y = ((row + d[0] + BLOCKS) % BLOCKS,
  92.                     (col + d[1] + BLOCKS) % BLOCKS)
  93.             if grid[x][y] == GREEN and not vis[(x, y)]:
  94.                 next_move, state = fsm[state][2:]
  95.             else:
  96.                 next_move, state = fsm[state][:2]
  97.  
  98.             if next_move == 1:
  99.                 d = LEFT[d]
  100.             elif next_move == 2:
  101.                 d = RIGHT[d]
  102.             else:
  103.                 row, col = x, y
  104.  
  105.         eat = FOOD - eat
  106.         if eat != 0:
  107.             eat += MOV_LIM
  108.         costs.append((i + p, eat))
  109.  
  110.     return costs
  111.  
  112.  
  113. def mutate(pop):
  114.     newpop = deepcopy(pop)
  115.     for i in range(POP):
  116.         fsm = newpop[i]
  117.         for j in range(STATES):
  118.             state = fsm[j]
  119.             for k in range(4):
  120.                 r = np.random.standard_normal()
  121.                 if k % 2 == 0:
  122.                     state[k] += 3 * r
  123.                     state[k] = int(round(state[k]))
  124.                     if state[k] >= 3 or state[k] < 0:
  125.                         state[k] = np.random.randint(3)
  126.                 else:
  127.                     state[k] += STATES * r
  128.                     state[k] = int(round(state[k]))
  129.                     if state[k] >= STATES or state[k] < 0:
  130.                         state[k] = np.random.randint(STATES)
  131.  
  132.     return newpop
  133.  
  134.  
  135. print(FOOD)
  136. for g in range(GEN):
  137.     c = cost(pop)
  138.     if g % 10 == 0:
  139.         print("Gen", g, "Min Cost =", min(c, key=lambda x: x[1])[1])
  140.     # newpop = mutate(pop)
  141.     newpop = gen_pop()
  142.     newcost = cost(newpop, p=POP)
  143.     c.extend(newcost)
  144.     c.sort(key=lambda x: x[1])
  145.     c = c[:POP]
  146.     ind = [c[i][0] for i in range(POP)]
  147.     tmp = []
  148.     for i in ind:
  149.         if i < 100:
  150.             tmp.append(pop[i])
  151.         else:
  152.             tmp.append(newpop[i - POP])
  153.     pop = tmp
  154.  
  155.  
  156. def color_block(pos, color):
  157.     block = [(MARGIN + SIZE) * pos[1] + MARGIN,
  158.              (MARGIN + SIZE) * pos[0] + MARGIN, SIZE, SIZE]
  159.     pygame.draw.rect(screen, color, block)
  160.  
  161.  
  162. pygame.init()
  163. pygame.display.set_caption("Artificial Ant Algorithm")
  164. screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
  165. clock = pygame.time.Clock()
  166.  
  167. fsm = pop[0]
  168. state = 0
  169.  
  170. itr = 0
  171. row = BLOCKS - 1
  172. col = 0
  173. d = (1, 0)
  174.  
  175. count = 0
  176.  
  177. while True:
  178.     for event in pygame.event.get():
  179.         if event.type == QUIT:
  180.             pygame.quit()
  181.             exit()
  182.  
  183.     screen.fill(BLACK)
  184.  
  185.     for i in range(BLOCKS):
  186.         for j in range(BLOCKS):
  187.             color_block((i, j), grid[i][j])
  188.  
  189.     color_block((row, col), BLUE)
  190.     if grid[row][col] == GREEN:
  191.         grid[row][col] = RED
  192.         color_block((row, col), RED)
  193.  
  194.     if count == MOV_LIM:
  195.         pygame.time.delay(5000)
  196.         exit()
  197.  
  198.     count += 1
  199.  
  200.     sense_food = False
  201.     next_pos = ((row + d[0] + BLOCKS) % BLOCKS,
  202.                 (col + d[1] + BLOCKS) % BLOCKS)
  203.  
  204.     if grid[next_pos[0]][next_pos[1]] == GREEN:
  205.         sense_food = True
  206.  
  207.     if sense_food:
  208.         next_move, state = fsm[state][2:]
  209.     else:
  210.         next_move, state = fsm[state][:2]
  211.  
  212.     itr += 1
  213.     if next_move == 1:
  214.         d = LEFT[d]
  215.     elif next_move == 2:
  216.         d = RIGHT[d]
  217.     else:
  218.         if grid[row][col] != RED:
  219.             grid[row][col] = BLACK
  220.         row, col = next_pos
  221.  
  222.     clock.tick(FPS)
  223.     pygame.display.update()
  224.  
  225.  
  226. pygame.quit()
Add Comment
Please, Sign In to add comment