Algoritmos genéticos
Guido García · @palmerabollo
#tefcon2014
"I have called this principle, by which each slight variation, if useful, is preserved, by the term of Natural Selection"
extatosoma tiaratum
3.5 MHz - 48 KB
28 años después
x 1
x 100000
10 FOR i = 1 TO 10
20 PRINT "Hola Mundo!"
30 NEXT
40 END
28 años después
Mismo código
Problema
Solución
conocimiento e inteligencia humanos
imperativo
determinístico
"Programming should be more about the what and less about the how"
ALGORITMOS GENÉTICOS
Optimización
optimización
inspirada en la naturaleza
Mejor solución
Posibles soluciones
(población)
selección natural
Problema
parametrizable
var population = [..., ..., ...]; // i.e. random
while (true) {
population = population.filter(function (individual) {
return fitness(individual) > THRESHOLD;
});
population.crossover();
population.mutate();
}
var fitness = function (individual) {
return ...; // numeric fitness value
}
Fitness Function
Ejemplo · Diseñar un coche
GAlib (C++) lancet.mit.edu/ga
VoxCAD www.voxcad.com
EJEMPLO · Evolved CREATURES
EVALUABLE
DIVISIBLE
subóptimO
Antena, NASA 2006
Niigata (Japan), ambulancias
"MONA LISA"
40 minutos
Evolución de redes neuronales
TRADING · Wimbledon 2008 · Mathieu - Čilić
Ejemplo · n reinas
4
6
0
2
7
5
3
1
Codificación
del problema
(genoma ~ array de enteros)
Población inicial
4
6
0
2
7
5
3
1
4
6
0
2
7
5
3
1
4
6
0
2
7
5
3
1
4
6
0
2
7
5
3
1
4
6
0
2
7
5
3
1
4
6
0
2
7
5
3
1
Individuo 1
Individuo 2
Individuo 3
Individuo 4
Individuo 5
Individuo 6
Individuo N
...
Supervivencia
4
6
0
2
7
5
3
1
4
6
0
2
7
5
3
1
4
6
0
2
7
5
3
1
4
6
0
2
7
5
3
1
4
6
0
2
7
5
3
1
4
6
0
2
7
5
3
1
Individuo 1
Individuo 2
Individuo 3
Individuo 4
Individuo 5
Individuo 6
= 9
= 8
= 6
= 10
= 14
= 6
Fitness Function: número de reinas atacándose
Operadores genéticos
Cruce
4
3
1
4
0
2
7
7
0
3
4
0
2
5
3
1
Individuo 3
Individuo 6
4
3
1
4
0
2
7
7
0
3
4
0
2
5
3
1
= 6
= 6
= 8
= 5
Mutación
Individuo 3'
Individuo 6'
4
3
1
4
0
2
7
7
0
3
4
0
2
5
1
= 6
= 5
Individuo 3'
Individuo 6'
2
Javascript
Show me da code
var BOARD_SIZE = 8;
var Individual = function (genome) {
this.genome = genome || [0,0,0,0,0,0,0,0];
};
Individual.prototype.mutate = function (probability) {
};
Individual.prototype.crossover = function (mate) {
};
if (Math.random() > probability) {
return;
}
var column = _.random(BOARD_SIZE - 1);
this.genome[column] = _.random(BOARD_SIZE - 1);
var pivot = BOARD_SIZE / 2;
var child1 = this.genome.slice(0, pivot)
.concat(mate.genome.slice(pivot, BOARD_SIZE));
var child2 = mate.genome.slice(0, pivot)
.concat(this.genome.slice(pivot, BOARD_SIZE));
return [new Individual(child1), new Individual(child2)];
Individual.prototype.fitness = function () {
var errors = 0;
for (var i = 0; i < BOARD_SIZE; i++) {
for (var j = i+1; j < BOARD_SIZE; j++) {
if (this.genome[i] === this.genome[j]) {
errors++;
}
if (Math.abs(this.genome[i] - this.genome[j]) === j - i) {
errors++;
}
}
}
this.fitnessValue = errors;
};
var POPULATION_SIZE = 100;
var population = [];
for (var i=0; i<POPULATION_SIZE; i++) {
population.push(new Individual());
}
var evolve = function () {
setTimeout(evolve, 0);
};
evolve();
population.forEach(function (individual) {
individual.mutate(0.1);
individual.fitness();
});
population.sort(function (a, b) {
return a.fitnessValue - b.fitnessValue;
});
var children = population[0].crossover(population[1]);
population.splice(population.length - 2, 2, children[0], children[1]);
(Java, watchmaker)
Show me da code
CandidateFactory<int[]> factory = new AbstractCandidateFactory<int[]>() {
public int[] generateRandomCandidate(Random rng) {
int[] genome = new int[BOARD_SIZE];
for (int i = 0; i < BOARD_SIZE; i++) {
genome[i] = rng.nextInt(BOARD_SIZE);
}
return genome;
}
};
CandidateFactory
List<EvolutionaryOperator<int[]>> operators =
new LinkedList<EvolutionaryOperator<int[]>>();
operators.add(new IntArrayCrossover());
operators.add(new IntArrayMutation(new Probability(0.05d)));
EvolutionaryOperator<int[]> evolutionScheme =
new EvolutionPipeline<int[]>(operators);
EvolutionaryOperator, EvolutionPipeline
class BoardEvaluator implements FitnessEvaluator<int[]> {
public double getFitness(int[] genome, ...) {
int errors = 0;
for (int i = 0; i < genome.length; i++) {
for (int j=i+1; j < genome.length; j++) {
if (genome[i] == genome[j]) {
errors++;
}
if (Math.abs(genome[i] - genome[j]) == j - i) {
errors++;
}
}
}
return errors;
}
public boolean isNatural() {
return false;
}
}
FitnessEvaluator
EvolutionEngine<int[]> engine = new GenerationalEvolutionEngine<int[]>(
candidateFactory,
evolutionScheme,
fitnessEvaluator,
new RouletteWheelSelection(), // selection strategy
new MersenneTwisterRNG()); // random generator
engine.evolve(1000, // population size
1, // elitism
new TargetFitness(0, false));
EvolutionEngine
PROGRAMACIÓN GENÉTICA
"programming the unprogrammable"
Evolucionar código
def algorithm(x, y)
if x > 3:
return y + 5
else:
return y - 2
Imágenes: "Programming Collective Intelligence" O'Reilly, 2007
Chapter 11. Evolving Intelligence
syntax
tree
def algorithm(x, y)
if x > 3:
return y + 5
else:
return x * y
def algorithm(x, y)
if x > 3:
return y * 5 - 2
else:
return y - 2
Lisp
(defn algorithm [x, y]
(if (> x 3)
(+ y 5)
(- y 2)))
código ~ tree
fácil de manipular
clojure: github.com/vollmerm/fungp
Ejemplo · Hipotenusa
def gp_add(a, b): return a+b
def gp_sub(a, b): return a-b
def gp_mul(a, b): return a*b
def gp_pow(a): return a**2
def gp_sqrt(a): return math.sqrt(abs(a))
def main_run():
tree = GTree.GTreeGP()
tree.setParams(max_depth=4)
tree.evaluator += fitness_function
ga = GSimpleGA.GSimpleGA(tree)
ga.setParams(gp_terminals=['a', 'b'],
gp_function_prefix="gp")
ga.setElitism(True)
ga.setGenerations(200)
ga.setCrossoverRate(1.0)
ga.setMutationRate(0.05)
ga.setPopulationSize(100)
ga.setMinimax(Consts.minimaxType["minimize"])
ga()
print ga.bestIndividual()
def fitness_function(individual):
error = Util.ErrorAccumulator()
code = individual.getCompiledCode()
points = [(3,4,5), (0,0,0), (15, 20, 25)]
for (a,b,target) in points:
evaluated = eval(code)
error += (target, evaluated)
# penalize big trees
return error.getRMSE() * chromosome.getNodesCount()
gp_sqrt(gp_add(gp_mul(a, a), gp_pow(b)))
gp_add(a, gp_sqrt(b))
gp_sqrt(gp_add(gp_pow(a), gp_pow(b)))
gp_sqrt(gp_add(gp_sub(b, b), gp_add(gp_pow(a), gp_pow(b))))
Ejemplo · Santa Fe Trail
python (DEAP): deap.googlecode.com/hg-history/default/examples/gp/ant.py
Preguntas
Algoritmos genéticos · #tefcon2014
By Guido García
Algoritmos genéticos · #tefcon2014
Computación evolutiva: algoritmos genéticos, programación genética, y más.
- 10,305