internal void Mutar(Cromosoma cromosoma, int valorMax, Random random) { bool success = false; for (int i = 0; i < cromosoma.Genes.Count; i++) { if (GetFitnessGen(cromosoma, cromosoma.Genes[i]) > 0) { while (!success) { int gen = random.Next(0, valorMax); if (!cromosoma.Genes.Contains(gen)) { if (GetFitnessGen(cromosoma, gen).Equals(0)) { cromosoma.Genes[i] = gen; success = true; } } } } if (success) { break; } } }
public int GetFitnessGen(Cromosoma cromosoma, int gen) { int colisiones = 0; for (int j = 1; j < cromosoma.Genes.Count - gen; j++) { int aux = gen + j; if (aux < cromosoma.Genes.Count) { if (cromosoma.Genes[gen].Equals(cromosoma.Genes[gen + j] + j)) { cromosoma.Colisiones++; } if (cromosoma.Genes[gen].Equals(cromosoma.Genes[gen + j] - j)) { cromosoma.Colisiones++; } } aux = gen - j; if (aux > 0) { if (cromosoma.Genes[gen].Equals(cromosoma.Genes[gen - j] - j)) { cromosoma.Colisiones++; } if (cromosoma.Genes[gen].Equals(cromosoma.Genes[gen - j] + j)) { cromosoma.Colisiones++; } } } return(colisiones); }
/// <summary> /// Genera población inicial /// </summary> /// <param name="poblacion">número de individuos a generar</param> /// <returns></returns> private List <Cromosoma> GeneraPoblacion(int poblacion, int longitud, Random random) { List <Cromosoma> lstIndividuos = new List <Cromosoma>(); for (int i = 0; i < poblacion; i++) { Cromosoma cromosoma = new Cromosoma(); cromosoma.Numero = i; cromosoma.Genes = GeneraGenesCromosoma(longitud, random); lstIndividuos.Add(cromosoma); } return(lstIndividuos); }
/// <summary> /// Obtiene el fitness de un sólo individuo /// </summary> /// <param name="cromosoma">cromosoma a analizar</param> /// <param name="lstTablero">tablero actual</param> /// <returns></returns> public int ObtenerFitnessCromosoma(Cromosoma cromosoma) { this.fitnessPoblacion = 0; cromosoma.Colisiones = 0; for (int i = 0; i < cromosoma.Genes.Count; i++) { for (int j = 1; j < cromosoma.Genes.Count - i; j++) { int aux = i + j; if (aux < cromosoma.Genes.Count) { if (cromosoma.Genes[i].Equals(cromosoma.Genes[i + j] + j)) { cromosoma.Colisiones++; } if (cromosoma.Genes[i].Equals(cromosoma.Genes[i + j] - j)) { cromosoma.Colisiones++; } } aux = i - j; if (aux > 0) { if (cromosoma.Genes[i].Equals(cromosoma.Genes[i - j] - j)) { cromosoma.Colisiones++; } if (cromosoma.Genes[i].Equals(cromosoma.Genes[i - j] + j)) { cromosoma.Colisiones++; } } } } double peorCaso = cromosoma.Genes.Count * (cromosoma.Genes.Count - 1); double penalizacion = cromosoma.Colisiones / peorCaso; cromosoma.Fitness = 1 - penalizacion; return(cromosoma.Colisiones); }
/// <summary> /// Aplica crossover de dos individuos /// </summary> /// <param name="cromosoma1">primer hijo.</param> /// <param name="cromosoma2">segundo hijo.</param> /// <returns>retorna una lista de los nuevos hijos generados.</returns> public List <Cromosoma> CrossOver(Cromosoma cromosoma1, Cromosoma cromosoma2, Random random) { List <Cromosoma> lstCromosomas = new List <Cromosoma>(); Cromosoma hijo1 = new Cromosoma(); Cromosoma hijo2 = new Cromosoma(); int interseccion = (cromosoma1.Genes.Count - 1) / 2; for (int i = 0; i < cromosoma1.Genes.Count; i++) { bool success = false; if (i <= interseccion) { hijo1.Genes.Add(cromosoma1.Genes[i]); } else { if (!hijo1.Genes.Contains(cromosoma2.Genes[i])) { hijo1.Genes.Add(cromosoma2.Genes[i]); } else { while (!success) { int gen = random.Next(0, cromosoma1.Genes.Count - 1); if (success = !hijo1.Genes.Contains(gen)) { hijo1.Genes.Add(gen); } else { gen = gen + 1; if (success = (gen <= cromosoma1.Genes.Count - 1 && !hijo1.Genes.Contains(gen))) { hijo1.Genes.Add(gen); } else { gen = gen - 2; if (success = (gen >= 0 && !hijo1.Genes.Contains(gen))) { hijo1.Genes.Add(gen); } } } } } } } for (int i = hijo1.Genes.Count; i > 0; i--) { hijo2.Genes.Add(hijo1.Genes[i - 1]); } lstCromosomas.Add(hijo1); lstCromosomas.Add(hijo2); return(lstCromosomas); }