Prelude
In the beginning, there was nothing and God said Let there be light
and there was light. He then continued to create earth and sky, and stars, and animals, and plants, and he saw that it was good. So he finally created humans. In retrospective, we should have been worried about the lack of unit testing and documentation, but all in all that’s how a software project should work. Only that it involves so much thinking. Not only you have to know, how your creations will interact with the environment, but also with the other creatures.
As far as nature is concerned, chances are, that this is not what happened. More likely is the following: In the beginning, there was nothing, then some milliard years later, there was the earth and even later, there started some complex chemical compounds to evolve, forming life. The lifeforms better fitted for their environment would reproduce, the more unfortunate would bite the dust, that’s evolution. Thus the surviving organisms would be better fitted for their surroundings. This goes on since then, with the latest idea
of nature being human able to think about all these things.
Nowadays, we often come to problems, where the solution is not quite obvious and often enough, it is not possible to find the perfect solution by thinking alone. That’s even true for numeric optimization problems. Then some smart guys thought about this: What if you could just use the same trick, nature used to come up with a good enough solution to the problem What’s the best way to survive on planet Earth?
This is where genetic Algorithms come into play.
The Generic Genetic Algorithm
So a genetic algorithm imitates the behavior of systems of organisms to find a good enough solution for a problem. But what is good enough
? And what is a solution?
Natural Born Killers
For a genetic algorithm to work, we need the general form of our solution. That is, a set of parameters. Suppose for example, you programmed an Ego-shooter and now you need to come up with an AI, that can compete with a human player. You already parametrized the behavior on some scales:
- Aggressive vs Passive
- Moving fast vs Shooting precise
- Favorite Weapon
- …
Now all you need to do is to find the most efficient combination of the parameters (or rather some very good ones). That is, as a mathematician might put it, highly non-trivial, AKA f*cking hard. However since you already finished the game logic… it should be easy, to set Bots against Bots.
So you begin with some random Bots (say 100), that probably wouldn’t outperform a 2 year old in tactical knowledge. However you can put them in the arena and make them fight to the death. Besides giving you the possibility to laugh diabolically and feel like a roman emperor it shows you what parameters are best. You laugh even more diabolically and kill the 90 worst competitors off. Now you have a set of 10 rather good parameters, but you can surely do better. You could just produce new random guesses and always filter out the best, but that would ignore the fact, that you already have some good guesses. Instead you combine them to get a new generation – you could think of that as making them mate, you dirty boy/girl.
Just choose random pairs and combine them in some reasonable way. So the child of an very aggressive and a rather passive parent might be a little more aggressive than the mean and the favorite weapon is randomly chosen from the parents. Do that until you have enough (for example 100, because that’s where you started).
Now you can just repeat that until you’re happy
However there are other possibilities: You could introduce mutations, that is randomly changing some parameters marginally. That could help, if your first guesses were not quite as good as you might need.
As you can easily imagine, this principle runs into a problem, if there are several highs
, you will stick with one and that might not be the best. You are prone to find a local maximum instead of a global one. It seams reasonable, that aggressive, accurate bots and passive, fast bots would perform well, but interbreeding them would produce not very useful ones. There are ways around that, but for now, we’ll keep it simple.
Cooking the Primordial Soup
As we’ve seen, there are some simple steps, that can give you a very simple genetic algorithm:
- find the parameters of your solution.
- figure out a function, that chooses the best individuals out of a population of parameter sets.
- come up with a reasonable way to combine some individuals to produce new ones.
- Implement mutations if you like.
- start with random values and iterate.
Now you can plug in what ever you like.
Have fun.