logo

Algoritmes genètics

Els algorismes genètics (GA) són algorismes de cerca heurístics adaptatius que pertanyen a la major part dels algorismes evolutius. Els algorismes genètics es basen en les idees de selecció natural i genètica. Es tracta d'una explotació intel·ligent de cerques aleatòries proporcionades amb dades històriques per dirigir la cerca a la regió de millor rendiment a l'espai de solucions. S'utilitzen habitualment per generar solucions d'alta qualitat per a problemes d'optimització i problemes de cerca.

Els algorismes genètics simulen el procés de selecció natural el que significa que aquelles espècies que poden adaptar-se als canvis del seu entorn poden sobreviure i reproduir-se i passar a la següent generació. En paraules senzilles, simulen la supervivència del més apte entre els individus de generacions consecutives per resoldre un problema. Cada generació està formada per una població d'individus i cada individu representa un punt en l'espai de cerca i possible solució. Cada individu es representa com una cadena de caràcters/enters/float/bits. Aquesta cadena és anàloga al cromosoma.



Fundació d'Algoritmes Genètics

Els algorismes genètics es basen en una analogia amb l'estructura genètica i el comportament dels cromosomes de la població. A continuació es mostren els fonaments dels GA basats en aquesta analogia:

  1. Els individus de la població competeixen pels recursos i s'aparellen
  2. Aquells individus que tenen èxit (més aptes) s'aparellen per crear més descendència que altres
  3. Els gens del progenitor més apte es propaguen al llarg de la generació, és a dir, de vegades els pares creen descendència que és millor que qualsevol dels pares.
  4. Així, cada generació successiva és més adequada per al seu entorn.

Espai de cerca

La població d'individus es manté dins de l'espai de cerca. Cada individu representa una solució a l'espai de cerca d'un problema donat. Cada individu està codificat com un vector de longitud finita (anàleg al cromosoma) de components. Aquests components variables són anàlegs als gens. Així, un cromosoma (individu) està format per diversos gens (components variables).



Puntuació de fitness

Es dóna una puntuació de forma física a cada individu que mostra la capacitat d'un individu per competir . Es busca l'individu que tingui una puntuació de forma física òptima (o gairebé òptima).

El GA manté la població de n individus (cromosoma/solucions) juntament amb les seves puntuacions de condició física. Els individus que tenen millors puntuacions de condició física tenen més possibilitats de reproduir-se que els altres. Es seleccionen els individus amb millors puntuacions de forma física que s'aparellen i produeixen millor descendència mitjançant la combinació de cromosomes dels pares. La mida de la població és estàtica, de manera que s'ha de crear la sala per als nouvinguts. Així, alguns individus moren i són substituïts per nou arribats, creant finalment una nova generació quan s'esgota tota l'oportunitat d'aparellament de la població vella. S'espera que al llarg de les generacions successives arribin millors solucions mentre els menys aptes morin.

Cada nova generació té de mitjana més gens millors que l'individu (solució) de les generacions anteriors. Així, cada nova generació té millor solucions parcials que les generacions anteriors. Una vegada que la descendència produïda no té cap diferència significativa amb la descendència produïda per poblacions anteriors, la població convergeix. Es diu que l'algorisme convergeix a un conjunt de solucions per al problema.



Operadors d'algorismes genètics

Un cop creada la generació inicial, l'algoritme fa evolucionar la generació utilitzant els següents operadors:
1) Operador de selecció: La idea és donar preferència als individus amb bons resultats físics i permetre'ls transmetre els seus gens a generacions successives.
2) Operador de crossover: Això representa l'aparellament entre individus. Es seleccionen dues persones mitjançant l'operador de selecció i els llocs d'encreuament es trien aleatòriament. A continuació, els gens d'aquests llocs d'encreuament s'intercanvien creant així un individu completament nou (descendencia). Per exemple -

3) Operador de mutació: La idea clau és inserir gens aleatoris en la descendència per mantenir la diversitat de la població per evitar una convergència prematura. Per exemple -

conceptes bàsics de java

Tot l'algorisme es pot resumir com:

1) Randomly initialize populations p 2) Determine fitness of population 3) Until convergence repeat:  a) Select parents from population  b) Crossover and generate new population  c) Perform mutation on new population  d) Calculate fitness for new population>

Exemple de problema i solució utilitzant algorismes genètics

Donada una cadena objectiu, l'objectiu és produir una cadena objectiu a partir d'una cadena aleatòria de la mateixa longitud. En la implementació següent, es fan les analogies següents:

  • Els caràcters A-Z, a-z, 0-9 i altres símbols especials es consideren gens
  • Una cadena generada per aquests caràcters es considera cromosoma/solució/individu

Puntuació de fitness és el nombre de caràcters que difereixen dels caràcters de la cadena de destinació en un índex concret. Així, la persona que té un valor físic més baix té més preferència.

C++




cadena en mètodes java

// C++ program to create target string, starting from> // random string using Genetic Algorithm> > #include> using> namespace> std;> > // Number of individuals in each generation> #define POPULATION_SIZE 100> > // Valid Genes> const> string GENES =>'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP'>> 'QRSTUVWXYZ 1234567890, .-;:_!'#%&/()=?@${[]}'>;> > // Target string to be generated> const> string TARGET =>'I love techcodeview.com'>;> > // Function to generate random numbers in given range> int> random_num(>int> start,>int> end)> {> >int> range = (end-start)+1;> >int> random_int = start+(>rand>()%range);> >return> random_int;> }> > // Create random genes for mutation> char> mutated_genes()> {> >int> len = GENES.size();> >int> r = random_num(0, len-1);> >return> GENES[r];> }> > // create chromosome or string of genes> string create_gnome()> {> >int> len = TARGET.size();> >string gnome =>''>;> >for>(>int> i = 0;i gnome += mutated_genes(); return gnome; } // Class representing individual in population class Individual { public: string chromosome; int fitness; Individual(string chromosome); Individual mate(Individual parent2); int cal_fitness(); }; Individual::Individual(string chromosome) { this->cromosoma = cromosoma; fitness = cal_fitness(); }; // Realitzar l'aparellament i produir una nova descendència Individual Individual::mate(Individual par2) { // cromosoma per a la descendència string child_chromosome = ''; int len ​​= chromosome.size(); for(int i = 0;i { // probabilitat aleatòria flotant p = random_num(0, 100)/100; // si prob és inferior a 0,45, inseriu el gen // del pare 1 if(p<0.45) child_chromosome += chromosome[i]; // if prob is between 0.45 and 0.90, insert // gene from parent 2 else if(p <0.90) child_chromosome += par2.chromosome[i]; // otherwise insert random gene(mutate), // for maintaining diversity else child_chromosome += mutated_genes(); } // create new Individual(offspring) using // generated chromosome for offspring return Individual(child_chromosome); }; // Calculate fitness score, it is the number of // characters in string which differ from target // string. int Individual::cal_fitness() { int len = TARGET.size(); int fitness = 0; for(int i = 0;i { if(chromosome[i] != TARGET[i]) fitness++; } return fitness; }; // Overloading bool operator<(const Individual &ind1, const Individual &ind2) { return ind1.fitness } // Driver code int main() { srand((unsigned)(time(0))); // current generation int generation = 0; vector population; bool found = false; // create initial population for(int i = 0;i { string gnome = create_gnome(); population.push_back(Individual(gnome)); } while(! found) { // sort the population in increasing order of fitness score sort(population.begin(), population.end()); // if the individual having lowest fitness score ie. // 0 then we know that we have reached to the target // and break the loop if(population[0].fitness <= 0) { found = true; break; } // Otherwise generate new offsprings for new generation vector new_generation; // Perform Elitism, that mean 10% of fittest population // goes to the next generation int s = (10*POPULATION_SIZE)/100; for(int i = 0;i new_generation.push_back(population[i]); // From 50% of fittest population, Individuals // will mate to produce offspring s = (90*POPULATION_SIZE)/100; for(int i = 0;i { int len = population.size(); int r = random_num(0, 50); Individual parent1 = population[r]; r = random_num(0, 50); Individual parent2 = population[r]; Individual offspring = parent1.mate(parent2); new_generation.push_back(offspring); } population = new_generation; cout<< 'Generation: ' << generation << ' '; cout<< 'String: '<< population[0].chromosome <<' '; cout<< 'Fitness: '<< population[0].fitness << ' '; generation++; } cout<< 'Generation: ' << generation << ' '; cout<< 'String: '<< population[0].chromosome <<' '; cout<< 'Fitness: '<< population[0].fitness << ' '; }>

>

>

Java




fotos d'icloud a Android

import> java.util.ArrayList;> import> java.util.Collections;> import> java.util.List;> import> java.util.Random;> > public> class> GeneticAlgorithm {> >// Number of individuals in each generation> >private> static> final> int> POPULATION_SIZE =>100>;> > >// Valid Genes> >private> static> final> String GENES =>'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890, .-;:_!'#%&/()=?@${[]}'>;> > >// Target string to be generated> >private> static> final> String TARGET =>'I love techcodeview.com'>;> > >// Function to generate random numbers in given range> >private> static> int> randomNum(>int> start,>int> end) {> >Random rand =>new> Random();> >return> rand.nextInt(end - start +>1>) + start;> >}> > >// Create random genes for mutation> >private> static> char> mutatedGenes() {> >int> len = GENES.length();> >int> r = randomNum(>0>, len ->1>);> >return> GENES.charAt(r);> >}> > >// Create chromosome or string of genes> >private> static> String createGnome() {> >int> len = TARGET.length();> >StringBuilder gnome =>new> StringBuilder();> >for> (>int> i =>0>; i gnome.append(mutatedGenes()); return gnome.toString(); } // Class representing individual in population private static class Individual implements Comparable { String chromosome; int fitness; Individual(String chromosome) { this.chromosome = chromosome; fitness = calFitness(); } // Perform mating and produce new offspring Individual mate(Individual par2) { StringBuilder childChromosome = new StringBuilder(); int len = chromosome.length(); for (int i = 0; i // random probability float p = randomNum(0, 100) / 100f; // if prob is less than 0.45, insert gene from parent 1 if (p <0.45) childChromosome.append(chromosome.charAt(i)); // if prob is between 0.45 and 0.90, insert gene from parent 2 else if (p <0.90) childChromosome.append(par2.chromosome.charAt(i)); // otherwise insert random gene(mutate), for maintaining diversity else childChromosome.append(mutatedGenes()); } // create new Individual(offspring) using generated chromosome for offspring return new Individual(childChromosome.toString()); } // Calculate fitness score, it is the number of characters in string which differ from target string private int calFitness() { int len = TARGET.length(); int fitness = 0; for (int i = 0; i if (chromosome.charAt(i) != TARGET.charAt(i)) fitness++; } return fitness; } @Override public int compareTo(Individual o) { return Integer.compare(this.fitness, o.fitness); } } // Driver code public static void main(String[] args) { // current generation int generation = 0; List population = new ArrayList(); boolean found = false; // create initial population for (int i = 0; i String gnome = createGnome(); population.add(new Individual(gnome)); } while (!found) { // sort the population in increasing order of fitness score Collections.sort(population); // if the individual having lowest fitness score i.e. 0 then we know that we have reached to the target // and break the loop if (population.get(0).fitness <= 0) { found = true; break; } // Otherwise generate new offsprings for new generation List newGeneration = new ArrayList(); // Perform Elitism, that mean 10% of fittest population goes to the next generation int s = (10 * POPULATION_SIZE) / 100; for (int i = 0; i newGeneration.add(population.get(i)); // From 50% of fittest population, Individuals will mate to produce offspring s = (90 * POPULATION_SIZE) / 100; for (int i = 0; i int len = population.size(); int r = randomNum(0, 50); Individual parent1 = population.get(r); r = randomNum(0, 50); Individual parent2 = population.get(r); Individual offspring = parent1.mate(parent2); newGeneration.add(offspring); } population = newGeneration; System.out.print('Generation: ' + generation + ' '); System.out.print('String: ' + population.get(0).chromosome + ' '); System.out.println('Fitness: ' + population.get(0).fitness); generation++; } System.out.print('Generation: ' + generation + ' '); System.out.print('String: ' + population.get(0).chromosome + ' '); System.out.println('Fitness: ' + population.get(0).fitness); } }>

>

>

Python 3




# Python3 program to create target string, starting from> # random string using Genetic Algorithm> > import> random> > # Number of individuals in each generation> POPULATION_SIZE>=> 100> > # Valid genes> GENES>=> '''abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP> QRSTUVWXYZ 1234567890, .-;:_!'#%&/()=?@${[]}'''> > # Target string to be generated> TARGET>=> 'I love techcodeview.com'> > class> Individual(>object>):> >'''> >Class representing individual in population> >'''> >def> __init__(>self>, chromosome):> >self>.chromosome>=> chromosome> >self>.fitness>=> self>.cal_fitness()> > >@classmethod> >def> mutated_genes(>self>):> >'''> >create random genes for mutation> >'''> >global> GENES> >gene>=> random.choice(GENES)> >return> gene> > >@classmethod> >def> create_gnome(>self>):> >'''> >create chromosome or string of genes> >'''> >global> TARGET> >gnome_len>=> len>(TARGET)> >return> [>self>.mutated_genes()>for> _>in> range>(gnome_len)]> > >def> mate(>self>, par2):> >'''> >Perform mating and produce new offspring> >'''> > ># chromosome for offspring> >child_chromosome>=> []> >for> gp1, gp2>in> zip>(>self>.chromosome, par2.chromosome):> > ># random probability> >prob>=> random.random()> > ># if prob is less than 0.45, insert gene> ># from parent 1> >if> prob <>0.45>:> >child_chromosome.append(gp1)> > ># if prob is between 0.45 and 0.90, insert> ># gene from parent 2> >elif> prob <>0.90>:> >child_chromosome.append(gp2)> > ># otherwise insert random gene(mutate),> ># for maintaining diversity> >else>:> >child_chromosome.append(>self>.mutated_genes())> > ># create new Individual(offspring) using> ># generated chromosome for offspring> >return> Individual(child_chromosome)> > >def> cal_fitness(>self>):> >'''> >Calculate fitness score, it is the number of> >characters in string which differ from target> >string.> >'''> >global> TARGET> >fitness>=> 0> >for> gs, gt>in> zip>(>self>.chromosome, TARGET):> >if> gs !>=> gt: fitness>+>=> 1> >return> fitness> > # Driver code> def> main():> >global> POPULATION_SIZE> > >#current generation> >generation>=> 1> > >found>=> False> >population>=> []> > ># create initial population> >for> _>in> range>(POPULATION_SIZE):> >gnome>=> Individual.create_gnome()> >population.append(Individual(gnome))> > >while> not> found:> > ># sort the population in increasing order of fitness score> >population>=> sorted>(population, key>=> lambda> x:x.fitness)> > ># if the individual having lowest fitness score ie.> ># 0 then we know that we have reached to the target> ># and break the loop> >if> population[>0>].fitness <>=> 0>:> >found>=> True> >break> > ># Otherwise generate new offsprings for new generation> >new_generation>=> []> > ># Perform Elitism, that mean 10% of fittest population> ># goes to the next generation> >s>=> int>((>10>*>POPULATION_SIZE)>/>100>)> >new_generation.extend(population[:s])> > ># From 50% of fittest population, Individuals> ># will mate to produce offspring> >s>=> int>((>90>*>POPULATION_SIZE)>/>100>)> >for> _>in> range>(s):> >parent1>=> random.choice(population[:>50>])> >parent2>=> random.choice(population[:>50>])> >child>=> parent1.mate(parent2)> >new_generation.append(child)> > >population>=> new_generation> > >print>(>'Generation: {} String: {} Fitness: {}'>.> >format>(generation,> >''.join(population[>0>].chromosome),> >population[>0>].fitness))> > >generation>+>=> 1> > > >print>(>'Generation: {} String: {} Fitness: {}'>.> >format>(generation,> >''.join(population[>0>].chromosome),> >population[>0>].fitness))> > if> __name__>=>=> '__main__'>:> >main()>

>

>

C#




programa de nombres primers en java
using> System;> using> System.Collections.Generic;> using> System.Linq;> > public> class> GeneticAlgorithm> {> >// Number of individuals in each generation> >private> const> int> POPULATION_SIZE = 100;> > >// Valid Genes> >private> const> string> GENES =>'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP'> +> >'QRSTUVWXYZ 1234567890, .-;:_!'#%&/()=?@${[]}'>;> > >// Target string to be generated> >private> const> string> TARGET =>'I love techcodeview.com'>;> > >private> static> readonly> Random random =>new> Random();> > >// Function to generate random numbers in given range> >private> static> int> RandomNum(>int> start,>int> end)> >{> >return> random.Next(start, end + 1);> >}> > >// Create random genes for mutation> >private> static> char> MutatedGenes()> >{> >int> len = GENES.Length;> >int> r = RandomNum(0, len - 1);> >return> GENES[r];> >}> > >// Create chromosome or string of genes> >private> static> string> CreateGnome()> >{> >int> len = TARGET.Length;> >char>[] gnome =>new> char>[len];> >for> (>int> i = 0; i { gnome[i] = MutatedGenes(); } return new string(gnome); } // Class representing individual in population private class Individual { public string Chromosome { get; } public int Fitness { get; } public Individual(string chromosome) { Chromosome = chromosome; Fitness = CalculateFitness(); } // Calculate fitness score, it is the number of // characters in string which differ from target string. private int CalculateFitness() { return Chromosome.Zip(TARGET, (a, b) =>a == b ? 0 : 1).Suma(); } // Realitzar l'aparellament i produir nous descendents Public Individual Mate(Individual parent2) { char[] childChromosome = new char[Chromosome.Length]; for (int i = 0; i { double p = aleatori.NextDouble(); si (p<0.45) childChromosome[i] = Chromosome[i]; else if (p <0.90) childChromosome[i] = parent2.Chromosome[i]; else childChromosome[i] = MutatedGenes(); } return new Individual(new string(childChromosome)); } } // Overloading private class FitnessComparer : IComparer { public int Compare(Individual ind1, Individual ind2) { return ind1.Fitness.CompareTo(ind2.Fitness); } } // Driver code public static void Main() { // current generation int generation = 0; List population = new List(); bool found = false; // create initial population for (int i = 0; i { string gnome = CreateGnome(); population.Add(new Individual(gnome)); } while (!found) { // sort the population in increasing order of fitness score population.Sort(new FitnessComparer()); // if the individual having lowest fitness score ie. // 0 then we know that we have reached the target // and break the loop if (population[0].Fitness == 0) { found = true; break; } // Otherwise generate new offsprings for new generation List newGeneration = new List(); // Perform Elitism, that means 10% of fittest population // goes to the next generation int s = (10 * POPULATION_SIZE) / 100; for (int i = 0; i newGeneration.Add(population[i]); // From 50% of fittest population, Individuals // will mate to produce offspring s = (90 * POPULATION_SIZE) / 100; for (int i = 0; i { int len = population.Count; int r = RandomNum(0, 50); Individual parent1 = population[r]; r = RandomNum(0, 50); Individual parent2 = population[r]; Individual offspring = parent1.Mate(parent2); newGeneration.Add(offspring); } population = newGeneration; Console.WriteLine('Generation: ' + generation + ' ' + 'String: ' + population[0].Chromosome + ' ' + 'Fitness: ' + population[0].Fitness); generation++; } Console.WriteLine('Generation: ' + generation + ' ' + 'String: ' + population[0].Chromosome + ' ' + 'Fitness: ' + population[0].Fitness); } }>

>

>

Javascript


en ordre



// Number of individuals in each generation> const POPULATION_SIZE = 100;> > // Valid Genes> const GENES =>'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP'> +> >'QRSTUVWXYZ 1234567890, .-;:_!'#%&/()=?@${[]}'>;> > // Target string to be generated> const TARGET =>'I love techcodeview.com'>;> > // Function to generate random numbers in given range> function> RandomNum(start, end) {> >return> Math.floor(Math.random() * (end - start + 1)) + start;> }> > // Create random genes for mutation> function> MutatedGenes() {> >let len = GENES.length;> >let r = RandomNum(0, len - 1);> >return> GENES.charAt(r);> }> > // Create chromosome or string of genes> function> CreateGnome() {> >let len = TARGET.length;> >let gnome =>''>;> >for> (let i = 0; i gnome += MutatedGenes(); } return gnome; } // Class representing individual in population class Individual { constructor(chromosome) { this.Chromosome = chromosome; this.Fitness = this.CalculateFitness(); } // Calculate fitness score, it is the number of // characters in string which differ from target string. CalculateFitness() { let fitness = 0; for (let i = 0; i FitnessComparer.Compare(a, b)); // si l'individu que té la puntuació de forma física més baixa, és a dir. // 0 llavors sabem que hem assolit l'objectiu // i trencar el bucle if (population[0].Fitness === 0) { found = true; trencar; } // En cas contrari, genera nous descendents per a la nova generació let newGeneration = []; // Realitzeu elitisme, això vol dir que el 10% de la població més apta // passa a la següent generació let s = Math.floor((10 * POPULATION_SIZE) / 100); per (permet i = 0; i newGeneration.push(population[i]); // A partir del 50% de la població més apta, els individus // s'aparellaran per produir descendència s = Math.floor((90 * POPULATION_SIZE) / 100); per (sigui i = 0; deixem r = RandomNum(0, 50); deixem pare1 = població[r]; r = RandomNum(0, 50); deixem pare2 = població[r]; deixem descendència = pare1.Mate( parent2); newGeneration.push(descendencia) = newGeneration console.log('Generació: ' + generació + 'Cadena: ' + població [0].Chromosoma; ' ' + 'Fitness: ' + population[0].Fitness++ } console.log('Generation: ' + generation + ' ' + 'String: '); + població[0].Cromosoma + ' ' + 'Fitness: ' + població[0].Fitness } // Executar la funció principal Main(>'>);

> 

Sortida:

Generation: 1 String: tO{'-?=jH[k8=B4]Oe@} Fitness: 18 Generation: 2 String: tO{'-?=jH[k8=B4]Oe@} Fitness: 18 Generation: 3 String: .#lRWf9k_Ifslw #O$k_ Fitness: 17 Generation: 4 String: .-1Rq?9mHqk3Wo]3rek_ Fitness: 16 Generation: 5 String: .-1Rq?9mHqk3Wo]3rek_ Fitness: 16 Generation: 6 String: A#ldW) #lIkslw cVek) Fitness: 14 Generation: 7 String: A#ldW) #lIkslw cVek) Fitness: 14 Generation: 8 String: (, o x _x%Rs=, 6Peek3 Fitness: 13  .   .   .  Generation: 29 String: I lope Geeks#o, Geeks Fitness: 3 Generation: 30 String: I loMe GeeksfoBGeeks Fitness: 2 Generation: 31 String: I love Geeksfo0Geeks Fitness: 1 Generation: 32 String: I love Geeksfo0Geeks Fitness: 1 Generation: 33 String: I love Geeksfo0Geeks Fitness: 1 Generation: 34 String: I love techcodeview.com Fitness: 0>

Nota: Cada algorisme comença amb cadenes aleatòries, de manera que la sortida pot ser diferent

Com podem veure a la sortida, el nostre algorisme de vegades s'enganxa a una solució òptima local, això es pot millorar encara més actualitzant l'algoritme de càlcul de la puntuació de fitness o ajustant els operadors de mutació i crossover.

Per què utilitzar algorismes genètics

  • Són robusts
  • Proporcioneu optimització en estat d'espai gran.
  • A diferència de la IA tradicional, no es trenquen amb un lleuger canvi d'entrada o presència de soroll

Aplicació d'algorismes genètics

Els algorismes genètics tenen moltes aplicacions, algunes d'elles són:

  • Xarxa neuronal recurrent
  • Prova de mutació
  • Trencament de codi
  • Filtrat i processament del senyal
  • Aprendre bases de regles difuses, etc