logo

Algoritmi genetici

Algoritmii genetici (GA) sunt algoritmi de căutare euristică adaptivă care aparțin celei mai mari părți a algoritmilor evolutivi. Algoritmii genetici se bazează pe ideile de selecție naturală și genetică. Acestea sunt exploatarea inteligentă a căutărilor aleatorii furnizate cu date istorice pentru a direcționa căutarea în regiunea de performanță mai bună în spațiul soluției. Ele sunt utilizate în mod obișnuit pentru a genera soluții de înaltă calitate pentru probleme de optimizare și probleme de căutare.

Algoritmii genetici simulează procesul de selecție naturală ceea ce înseamnă că acele specii care se pot adapta la schimbările din mediul lor pot supraviețui și se pot reproduce și trec la următoarea generație. Cu cuvinte simple, ele simulează supraviețuirea celui mai apt dintre indivizii din generații consecutive pentru a rezolva o problemă. Fiecare generație este formată dintr-o populație de indivizi iar fiecare individ reprezintă un punct în spațiul de căutare și o posibilă soluție. Fiecare individ este reprezentat ca un șir de caractere/întregi/float/biți. Acest șir este analog cu Cromozomul.



Fundația algoritmilor genetici

Algoritmii genetici se bazează pe o analogie cu structura genetică și comportamentul cromozomilor populației. Urmează fundamentul GA bazat pe această analogie -

  1. Indivizii din populație concurează pentru resurse și se împerechează
  2. Acei indivizi care au succes (mai potriviți) se împerechează apoi pentru a crea mai mulți descendenți decât alții
  3. Genele de la cel mai potrivit părinte se propagă de-a lungul generației, adică uneori părinții creează descendenți care sunt mai buni decât oricare dintre părinți.
  4. Astfel, fiecare generație succesivă este mai potrivită pentru mediul lor.

Spațiu de căutare

Populația de indivizi este menținută în spațiul de căutare. Fiecare individ reprezintă o soluție în spațiul de căutare pentru o anumită problemă. Fiecare individ este codificat ca un vector de lungime finită (analog cromozomului) al componentelor. Aceste componente variabile sunt analoge cu Genele. Astfel un cromozom (individ) este compus din mai multe gene (componente variabile).



Scor de fitness

Fiecărei persoane i se acordă un scor de fitness care arată capacitatea unui individ de a concura . Se caută persoana care are un scor de fitness optim (sau aproape optim).

GA menține populația de n indivizi (cromozom/soluții) împreună cu scorurile lor de fitness. Indivizilor care au scoruri de fitness mai bune li se oferă mai multe șanse de a se reproduce decât altora. Sunt selectați indivizii cu scoruri de fitness mai bune care se împerechează și produc urmași mai buni prin combinarea cromozomilor părinților. Dimensiunea populației este statică, așa că camera trebuie creată pentru noii sosiți. Așadar, unii indivizi mor și sunt înlocuiți de noi veniți, creând în cele din urmă o nouă generație atunci când toate oportunitățile de împerechere ale vechii populații sunt epuizate. Se speră că de-a lungul generațiilor succesive vor ajunge soluții mai bune, în timp ce mor cel mai puțin potrivit.

Fiecare nouă generație are în medie mai multe gene mai bune decât individul (soluția) generațiilor anterioare. Astfel, fiecare nouă generație are mai bine soluții parțiale decât generațiile anterioare. Odată ce descendenții produși nu au nicio diferență semnificativă față de descendenții produși de populațiile anterioare, populația este convergentă. Se spune că algoritmul este convergent către un set de soluții pentru problemă.



Operatori de algoritmi genetici

Odată ce generația inițială este creată, algoritmul dezvoltă generația folosind următorii operatori:
1) Operator de selecție: Ideea este de a da preferință indivizilor cu scoruri bune de fitness și de a le permite să-și transmită genele generațiilor succesive.
2) Operator crossover: Aceasta reprezintă împerecherea între indivizi. Două persoane sunt selectate folosind operatorul de selecție și site-urile de încrucișare sunt alese aleatoriu. Apoi, genele de la aceste site-uri de încrucișare sunt schimbate, creând astfel un individ complet nou (descendent). De exemplu -

3) Operator de mutație: Ideea cheie este de a introduce gene aleatorii în urmași pentru a menține diversitatea în populație pentru a evita convergența prematură. De exemplu -

chenar css

Întregul algoritm poate fi rezumat astfel:

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>

Exemplu de problemă și soluție folosind algoritmi genetici

Având în vedere un șir țintă, scopul este de a produce șir țintă pornind de la un șir aleatoriu de aceeași lungime. În implementarea următoare, se fac următoarele analogii:

  • Caracterele A-Z, a-z, 0-9 și alte simboluri speciale sunt considerate gene
  • Un șir generat de aceste caractere este considerat cromozom/soluție/Individ

Scorul de fitness este numărul de caractere care diferă de caracterele din șirul țintă la un anumit index. Deci, persoanei care au o valoare mai mică de fitness i se acordă mai multă preferință.

C++


ssis



// 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->cromozom = cromozom; fitness = cal_fitness(); }; // Efectuați împerechere și produceți noi descendenți Individual Individ::mate(Individual par2) { // cromozom pentru descendenți șir child_chromosome = ''; int len ​​= chromosome.size(); for(int i = 0;i { // probabilitate aleatorie float p = random_num(0, 100)/100; // dacă prob este mai mic de 0,45, inserați gena // din părintele 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




dezactivarea modului dezvoltator 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); } }>

>

>

Python3




# 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#


python scrie json în fișier



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(); } // Efectuați împerechere și produceți noi descendenți public Individual Mate(Individual parent2) { char[] childChromosome = new char[Chromosome.Length]; pentru (int i = 0; i { double p = aleatoriu.NextDouble(); dacă (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




// 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)); // dacă persoana care are cel mai mic scor de fitness, de exemplu. // 0 atunci știm că am atins ținta // și întrerupem bucla dacă (population[0].Fitness === 0) { found = true; pauză; } // În caz contrar, generează noi descendenți pentru noua generație let newGeneration = []; // Efectuați elitism, adică 10% din populația cea mai aptă // trece la generația următoare let s = Math.floor((10 * POPULATION_SIZE) / 100); pentru (să fie i = 0; i newGeneration.push(population[i]); // Din 50% din populația cea mai aptă, indivizii // se vor împerechea pentru a produce descendenți s = Math.floor((90 * POPULATION_SIZE) / 100); pentru (fie i = 0; i fie r = RandomNum(0, 50); fie părinte1 = populație[r]; r = Număr aleatoriu (0, 50); fie părinte2 = populație[r]; fie descendenți = părinte1.Mate( parent2); newGeneration.push(offspring); populație = newGeneration console.log('Generation: ' + generation + ' ' + 'String: ' + population[0]. ' ' + 'Fitness: ' + populație[0].Fitness++ } console.log('Generation: ' + generation + ' ' + 'String: '); + populație[0].Cromozom + ' ' + 'Fitness: ' + populație[0].Fitness } // Execută funcția principală (>'>);

> 

Ieșire:

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>

Notă: Algoritmul de fiecare dată începe cu șiruri aleatorii, astfel încât rezultatul poate diferi

După cum putem vedea din rezultat, algoritmul nostru s-a blocat uneori la o soluție optimă locală, aceasta poate fi îmbunătățită și mai mult prin actualizarea algoritmului de calcul al scorului de fitness sau prin ajustarea operatorilor de mutație și crossover.

De ce să folosiți algoritmi genetici

  • Sunt robusti
  • Oferă optimizare pentru starea spațială mare.
  • Spre deosebire de inteligența artificială tradițională, acestea nu se rup la o modificare ușoară a intrării sau prezența zgomotului

Aplicarea algoritmilor genetici

Algoritmii genetici au multe aplicații, unele dintre ele sunt:

  • Rețeaua neuronală recurentă
  • Testarea mutațiilor
  • Încălcarea codului
  • Filtrare și procesare a semnalului
  • Învățarea bazei de reguli fuzzy etc

gol 0