Genetic Algorithms


AI That Evolves?


Tips: Many of the rockets will start to follow a similar pattern as a dominant set of genes emerges. At this point there is very little genetic diversity and the rockets must rely on mutation rate for any increases in fitness. This is alright if they've already found the target, but can limit learning if they have not yet found the target. You can combat this by starting off with larger populations or with a large mutation rate. This increases genetic diversity. Large mutation rates however can lead to some very random results, so it is generally nice to have higher elitism rates with high mutation rate so that the best rockets of the previous generation stick around and dont mutate away.

After binge watching all of the "Nature of Code" videos by Daniel Shiffman, I became very interested in recreating natural movements and systems with code. This project is a product of this interest in AI and how genetic algorithms allow for synthetic organisms to "learn" a set behavior. Although Daniel Shiffman was a big influence on my initial attempt at creating a gentic algorithm, much of the underlying code for the Genetic Algorithm of this project is thanks to Tiago Figueiredo's Youtube channel "Kryzarel", and his video tutorial on genetic algorithms. Infact, I included his implemented version of a Genetic Algorithm in this project, which is the text generator. I decided to include his project side by side with my "Smart Rockets" project to show how two seemingly unrelated projects actually share a lot of code in how they function! This is possible because all Genetic Algorithms at a fundamental level do very similar things, no matter what problem they are solving. They all randomly generate a population of DNA objects which hold a randomly generated list of Genes in each DNA. These DNA objects then have their "Fitness" tested and compared amongst each other. This population of DNA then goes through a "Crossover" phase where they mate and pass on their Genes to create new DNA children with a combination of both parent's genes. In this crossover phase, the DNA with the highest fitness have a greater chance of mating so that the next generation is hopefully more fit than the previous. Once the children have their fitness tested this cycle repeates until the population converges on a set DNA pattern of genes as genetic diversity slowly dwindles. To combat this this loss of genetic diversity, a "Mutation Rate" is applied which allows each child born to have the possibility of randomly having a new different gene from its parents.

Basically, a Genetic algorithm:
generates a Random population -> population is tested for fitness -> most fit of population breed -> children are born and have their fitness tested -> children breed, and the cycle continues.

Because genetic algorithms share so much functionality at a base level, Tiago wrote some excellent code using generics which allows different genetic algorithm implementations to extend off the same code. The text generator and smart rockets actually run off of about 40% of the same code! This is very interesting as, at first first glance, the two projects seem to be completely unrelated. But, in fact, they have the same code in many aspects, such as how parents are selected and breed, as well as how children are born and mutated.

Despite having the same underlying genetic algorithm, the two projects have many differences as well. The main difference being in the overal structure of their "Genes" and also how these Genes are interpreted into physical behavior, refered to as Phenotype. Tiago's text generator's DNA is made up of genes which hold a single character of the alphabet. These genes can then string together to form a sentence. For example a DNA may be the sentence, "To be or not to be." The first Gene in this DNA would be the letter "T" and the second Gene would be the letter "o". So In Tiago's project the Genotype and Phenotype are actually the same because one gene is one letter of the alphabet and the phenotype, the interpretation of this gene, is simply printing out this (gene)letter.

In my Smart Rockets project the Geneotype and Phenotype differ. One Gene in the DNA of a smart rocket is a 3 dimensional vector. The x and y axis values of this 3d vector are the direction that the 2 dimensional smart rocket will fly in. The z axis value of the gene scales the rocket's speed when traveling in that direction. So, this means each smart rocket interprets each 3d vector gene as a 2d vector direction to fly in at a set speed dictated by the z value of the gene. A smart rocket could then have DNA with 10 genes, and therefor fly in these directions at the speed dictated by each gene one after another. The DNA of these smart rockets is essentialy just a roadmap of directions to fly in at specific speeds. I chose to have each gene active for 0.25 seconds of flight arbitrarily, and this is a set value for every gene. So a DNA with 10 3-d vectors equals 2.5 seconds of total flight time in 10 different directions at 10 different speeds.

Another aspect that differs between these two projects is how the fitness is calculated. For Tiago's project fitness is calculated by how closely the randomly generated text matches the input text. If the input text was "Hey" and the randomly generated text was "Hat" only 1/3 letters match so this could have a fitness of 0.33.

For my project, fitness is calculated as the inverse of the distance from the target when the rocket collides with something. So, fitness aproaches zero when it's far from the target, and fitness equals 1 when it hits the target. I also weighted the x-axis distance to be more important than the y-axis distance from the target so that rockets have more fitness if they are able to find a way around an obstacle and go further to the right on the screen. Additionally, fitness is calculated at an exponential scale, so that rockets that make it a little bit closer to the target actually have a much higher fitness and are more likely to breed.