public void MutacionCruce() { PromedioMutaCruce.Clear(); Cadena objCad = new Cadena(); //Proceso de algoritmo genético for (int ciclo = 1; ciclo <= numCiclos; ciclo++) { //Toma dos individuos al azar int indivA = azar.Next(Individuos.Count); int indivB; do { indivB = azar.Next(Individuos.Count); } while (indivA == indivB); //Asegura que sean dos individuos distintos //Usa el operador cruce int posAzar = azar.Next(cadOriginal.Length); string parteA = Individuos[indivA].Substring(0, posAzar); string parteB = Individuos[indivB].Substring(posAzar); string HijoA = parteA + parteB; //Además muta el hijo HijoA = objCad.MutaCadena(azar, HijoA); //Evalúa la adaptación de los individuos padres e hijos int valorIndivA = objCad.EvaluaCadena(cadOriginal, Individuos[indivA]); int valorIndivB = objCad.EvaluaCadena(cadOriginal, Individuos[indivB]); int valorHijoA = objCad.EvaluaCadena(cadOriginal, HijoA); //Si los hijos son mejores que los padres, entonces los reemplaza if (valorHijoA > valorIndivA) { Individuos[indivA] = HijoA; } if (valorHijoA > valorIndivB) { Individuos[indivB] = HijoA; } //Calcula promedio de adaptación de toda la población if (ciclo % Promedio == 0) { double acumula = 0; for (int indiv = 0; indiv < Individuos.Count; indiv++) { acumula += objCad.EvaluaCadena(cadOriginal, Individuos[indiv]); } PromedioMutaCruce.Add((double)acumula / Individuos.Count); } } }
public void Configura(int semilla, string cadOriginal, int numIndividuos, int numCiclos, int Promedio) { azar = new Random(semilla); //Crea la población con individuos generados al azar (dependiendo de la semilla) Individuos.Clear(); Cadena objCad = new Cadena(); for (int cont = 1; cont <= numIndividuos; cont++) { Individuos.Add(objCad.CadenaAzar(azar, cadOriginal.Length)); } this.numCiclos = numCiclos; this.Promedio = Promedio; this.cadOriginal = cadOriginal; }
//Operador mutación public void Mutacion() { PromedioMuta.Clear(); Cadena objCad = new Cadena(); //Proceso de algoritmo genético for (int ciclo = 1; ciclo <= numCiclos; ciclo++) { //Toma dos individuos al azar int indivA = azar.Next(Individuos.Count); int indivB; do { indivB = azar.Next(Individuos.Count); } while (indivA == indivB); //Asegura que sean dos individuos distintos //Evalúa la adaptación de los dos individuos int valorIndivA = objCad.EvaluaCadena(cadOriginal, Individuos[indivA]); int valorIndivB = objCad.EvaluaCadena(cadOriginal, Individuos[indivB]); //Si individuo A está mejor adaptado que B entonces: Elimina B + Duplica A + Modifica duplicado if (valorIndivA > valorIndivB) { Individuos[indivB] = objCad.MutaCadena(azar, Individuos[indivA]); } else if (valorIndivA < valorIndivB) //Caso A es menor que B: Elimina A + Duplica B + Modifica duplicado { Individuos[indivA] = objCad.MutaCadena(azar, Individuos[indivB]); } //Calcula promedio de adaptación de toda la población if (ciclo % Promedio == 0) { double acumula = 0; for (int indiv = 0; indiv < Individuos.Count; indiv++) { acumula += objCad.EvaluaCadena(cadOriginal, Individuos[indiv]); } PromedioMuta.Add((double)acumula / Individuos.Count); } } }
static void Main() { Random azar = new Random(); //Usado para la semilla del generador de aleatorios de la clase población //Cadena que será buscada por los algoritmos genéticos Cadena objCad = new Cadena(); string cadOriginal; int Pruebas = 50; //Total de veces que se cambiará la cadena y se repetirá todo el proceso int TotalIndividuos = 2000; //Total de individuos de la población int TotalCiclos = 100000; //Total de ciclos que hará por cada operador int Promedio = 1000; //Cada cuanto calcula el promedio de la población int TamCadena = 90; //Tamaño de la cadena a buscar Poblacion objPoblacion = new Poblacion(); List <double> Muta = new List <double>(); //Lista de promedios de adaptación del operador de mutación List <double> Cruce = new List <double>(); //Lista de promedios de adaptación del operador de cruce List <double> MutaCruce = new List <double>(); //Lista de promedios de adaptación del operador de mutación+cruce for (int num = 0; num < TotalCiclos / Promedio; num++) { Muta.Add(0); Cruce.Add(0); MutaCruce.Add(0); } //En cada prueba se cambia la cadena a buscar y se reinicia las poblaciones con nuevos individuos for (int num = 0; num < Pruebas; num++) { int semilla = azar.Next(); cadOriginal = objCad.CadenaAzar(azar, TamCadena); //Misma semilla para que los tres operadores trabajen con los mismos individuos al inicio objPoblacion.Configura(semilla, cadOriginal, TotalIndividuos, TotalCiclos, Promedio); objPoblacion.Mutacion(); objPoblacion.Configura(semilla, cadOriginal, TotalIndividuos, TotalCiclos, Promedio); objPoblacion.Cruce(); objPoblacion.Configura(semilla, cadOriginal, TotalIndividuos, TotalCiclos, Promedio); objPoblacion.MutacionCruce(); //Para el promedio de evolución de las métricas de acercamiento a la cadena original //de los tres operadores for (int cont = 0; cont < objPoblacion.PromedioMuta.Count; cont++) { Muta[cont] += objPoblacion.PromedioMuta[cont]; Cruce[cont] += objPoblacion.PromedioCruce[cont]; MutaCruce[cont] += objPoblacion.PromedioMutaCruce[cont]; } } //Calcula el promedio y lo muestra en consola. for (int num = 0; num < TotalCiclos / Promedio; num++) { Muta[num] /= Pruebas; Console.Write(Muta[num].ToString() + ";"); Cruce[num] /= Pruebas; Console.Write(Cruce[num].ToString() + ";"); MutaCruce[num] /= Pruebas; Console.WriteLine(MutaCruce[num].ToString()); } Console.ReadKey(); }