import pygame, sys from pygame.locals import * import time import random from operator import * import traceback import os import getpass import cPickle as pickle class GA: def __init__(self, num_samples = 1, num_selected = 1, mutation_factor = 4): pygame.init() pygame.display.init() self.screen = pygame.display.set_mode((152, 200), 0, 32) while True: try: print "128 and 256 are good choices. 256 is better but also slower." self.ncircles = input("Enter number of circles you want to use: ") break except NameError: print "Must enter an integer!" except SyntaxError: print "Must enter an integer!" grayscale = raw_input("Is this picture grayscale? Y/N\n") accept = ["y", "Y", "n", "N"] while grayscale not in accept: grayscale = raw_input("Is this picture grayscale? Y/N\n") if grayscale == "y" or grayscale == "Y": self.grayscale = True else: self.grayscale = False self.imgpath = raw_input("Enter full path of file, including file name and extension.\n") while os.path.exists(self.imgpath) is False: print "Path/file does not exist!" self.imgpath = raw_input("Enter full path of file, including file name and extension.\n") self.bg = pygame.image.load(self.imgpath).convert() self.width = self.bg.get_width() self.height = self.bg.get_height() self.path = "C:/users/" + str(getpass.getuser()) + "/desktop/imgs/" self.num_samples = num_samples self.num_selected = num_selected self.mutation_factor = mutation_factor self.target = self.get_target() def get_target(self): x = self.width y = self.height pixelData = [] for ypixel in xrange(0, y): for xpixel in xrange(0, x): pixelData.append(self.bg.get_at((xpixel, ypixel))) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() pygame.display.update() pygame.quit() return pixelData def get_state(self, screen): x = self.width y = self.height pixelData = [] for ypixel in xrange(0, y): for xpixel in xrange(0, x): pixelData.append(screen.get_at((xpixel, ypixel))) return pixelData def generate_random_chromosome(self): chromo = [] for n in xrange(1, self.ncircles+1): a = random.randint(0, 255) if self.grayscale: randcolor = (a,a,a, random.randint(0, 255)) else: randcolor = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) randpos = (random.randint(0, self.height), random.randint(0, self.width)) randradius = random.randint(1, self.height/3) chromo.append((n, randcolor, randpos, randradius)) print "Random chromosome generated." return chromo def fitness(self, chromo): pygame.init() s = pygame.Surface((self.width, self.height), flags=pygame.SRCALPHA) total_fitness = 0 for args in chromo: s.lock() pygame.draw.circle(s, args[1], args[2], args[3]) s.unlock() state = self.get_state(s) s.fill((0, 0, 0)) cpix = 0 for pixel in self.target: if self.grayscale: current_fitness = abs(pixel[0]-state[cpix][0]) else: current_fitness = abs(pixel[0]-state[cpix][0])+abs(pixel[1]-state[cpix][1])+abs(pixel[2]-state[cpix][2]) cpix += 1 total_fitness += current_fitness return total_fitness def mutate(self, chromo): mutations = 0 mutateTo = random.randint(1, self.mutation_factor) mutateChoice = ["color", "opacity", "pos", "radius", "swap"] while mutations < mutateTo: argchange = random.choice(mutateChoice) if argchange == "swap": swap1 = random.randint(0, len(chromo)-1) swap2 = random.randint(0, len(chromo)-1) while swap1 == swap2: swap2 = random.randint(0, len(chromo)-1) swapvalue1 = chromo[swap1] swapvalue2 = chromo[swap2] chromo[swap1] = swapvalue2 chromo[swap2] = swapvalue1 mutations += 1 else: argint = random.randint(0, len(chromo)-1) args = list(chromo[argint]) args[1] = list(args[1]) args[2] = list(args[2]) a = random.randint(0, 255) if argchange == "color": if self.grayscale: args[1][0] = a args[1][1] = a args[1][2] = a else: args[1][0] = random.randint(0, 255) args[1][1] = random.randint(0, 255) args[1][2] = random.randint(0, 255) elif argchange == "opacity": args[1][3] = random.randint(0, 255) elif argchange == "pos": args[2][0] = random.randint(0, self.width) args[2][1] = random.randint(0, self.height) elif argchange == "radius": args[3] = random.randint(1, self.height/3) args[2] = tuple(args[2]) args[1] = tuple(args[1]) args = tuple(args) chromo[argint] = args mutations += 1 return chromo def display(self, data, gen): bif = "C:/users/justin/pictures/charles-darwin.jpg" mif = "C:/users/justin/pictures/mouse.png" path = self.path + str(gen) + "-" + str(self.fitness(data)/10000) + ".png" pygame.init() screen = pygame.display.set_mode((self.width, self.height), 0, 32) s = pygame.Surface((self.width, self.height), flags=pygame.SRCALPHA) s.fill((0, 0, 0)) a = 0 while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() for args in data: s.lock() pygame.draw.circle(s, args[1], args[2], args[3]) s.unlock() screen.blit(s, (0, 0)) pygame.display.update() pygame.image.save(screen, path) screen.fill((0, 0, 0)) pygame.quit() break def run(self): #Creates a random chromosome sample = self.generate_random_chromosome() load_pickle = raw_input("Would you like to load the previous genome? Y/N\n") accept = ["y", "Y", "n", "N"] while load_pickle not in accept: load_pickle = raw_input("Would you like to load the previous genome? Y/N\n") if load_pickle == "y" or load_pickle == "Y": generation = pickle.load(open("ge.neration", "rb"))-1 mother = pickle.load(open("ge.nome", "rb")) else: generation = -1 mother = sample try: while self.fitness(sample) != 0: generation += 1 os.system("title Genetic Algorithm: Generation " + str(generation)) #Mutate the chromo temp = [] for args in mother: temp.append(args) daughter = self.mutate(mother) if self.fitness(temp) <= self.fitness(daughter): mother = temp new = False else: mother = daughter new = True print "The best chromosome of generation %s is %s" %( generation, self.fitness(mother)) if new: self.display(mother, generation) new = False if self.fitness(mother) <= 800000: self.mutation_factor = 1 except: pickle.dump(mother, open("ge.nome", "w")) pickle.dump(generation, open("ge.neration", "w")) raw_input("Press enter to quit...\n") if __name__ == "__main__": os.system("title Genetic Algorithm") print "You MUST have a folder called \"imgs\" without the quotes on your desktop." raw_input("Press enter to start the program.\n") ga = GA() ga.run()