As seen in action on the left, I built a simple genetic algorithm to get more familiar with what it is and how it works. I started by doing research into genetic biology to get a firm grasp about the fundamentals before moving on to building the basic steps of evolutionary computing in python.

This basic setup will function as my template for generating images from scratch based on any given source image. This might later be useful for potentially generating textures or even materials to be used in game engines such as Unreal Engine.

*Features: Darwinian Natural Selection (Heredity, Variation, Selection).*

# Paul Ambrosiussen - Technical Artist # Free Code Snippet (Genetic Algorithm) import time from math import pow from random import uniform, randrange ### USER TWEAKABLE PARAMETERS ### TargetPhrase = 'Hi, my name is Paul Ambrosiussen' PopulationCount = 600 MaxGenerations = 5000 #Possibility to lock max generation number, & MutationRate = 0.01 ### END USER TWEAKABLE PARAMETERS ### DNALength = len(TargetPhrase) Population = [] PopulationFitness = [] #This function returns a random character def GetRandomCharacter(): return chr(int(randrange(32, 126, 1))) #This function returns a random dataset with specified length def GetRandomDataSet(a_DNALength): return ''.join([GetRandomCharacter() for x in range(a_DNALength)]) #This function returns a random population def CreateRandomPopulation(): global Population Population = [GetRandomDataSet(DNALength) for x in range(PopulationCount)] PopulationFitness = range(PopulationCount) #This function calculates the fitness by comparing a DNA dataset to the target DNA def CalculateFitnessDNA(a_DNA): t_Fitness = sum([1 if a_DNA[x] == TargetPhrase[x] else 0 for x in range(len(a_DNA))]) return pow((t_Fitness / len(TargetPhrase)),2) #This function crosses two datasets by randomly picking from both parents def GetCrossover(a_Parent1, a_Parent2): return ''.join([a_Parent1[x] if uniform(0, 1) < 0.5 else a_Parent2[x] for x in range(len(a_Parent1))]) #This function performs a mutation on each genome in a specified DNA set based on a mutationchance probability def PerformMutation(a_DNA, a_MutationChance): return ''.join([GetRandomCharacter() if uniform(0, 1) < a_MutationChance else a_DNA[x] for x in range(len(a_DNA))]) #This function returns a weigthed random element from the Population def ReturnWeightedRandomParent(): t_weightedTotal = sum(PopulationFitness) t_treshold = uniform(0, t_weightedTotal) for x, weight in enumerate(PopulationFitness): t_weightedTotal -= weight if t_weightedTotal < t_treshold: return Population[x] #This function returns the most fit DNA (Closest to target DNA) def GetMostFitDNA(): t_Fitness = max(PopulationFitness) return [Population[PopulationFitness.index(t_Fitness)], str(round(t_Fitness,2)*100)[:4] +'%'] #This function sets the populationfitness for every member of the population def SetPopulationFitness(): global PopulationFitness PopulationFitness.clear() PopulationFitness = [CalculateFitnessDNA(x) for x in Population] #The main function of the script def MainFunction(): global Population, PopulationFitness t_StartTime = time.time() t_FittestScore, t_currentGeneration = 0, 0 ###1. Create a random population of N elements CreateRandomPopulation() #This is where the evolution loop happens while (t_FittestScore < 1 and t_currentGeneration < MaxGenerations): ###2. Calculate Fitness for every element in the population SetPopulationFitness() ###3. Reproduction -> Create New population t_newPopulation = [] for x in range(PopulationCount): # A. Create Probability for each element t_parents = [ReturnWeightedRandomParent(),ReturnWeightedRandomParent()] # B. Create new Dataset from 2 parents chosen through probability t_newChild = GetCrossover(t_parents[0],t_parents[1]) # C. Apply Probability Mutation to each Genome in DNA && Add to new population t_newPopulation.append(PerformMutation(t_newChild, MutationRate)) ###4. Replace Old Population with New Population from step 3 Population.clear() Population = t_newPopulation #Calculate fitness for new population to make sure we dont overshoot the evolution SetPopulationFitness() #Get highest fitness score, printing results to screen, and incrementing generation number t_FittestScore = max(PopulationFitness) print(GetMostFitDNA()) t_currentGeneration+=1 print('Execution Time: {0} seconds, with {1} Generations'.format(round((time.time()-t_StartTime),3), t_currentGeneration)) exit(0) MainFunction()