public static void printaMelhorCromossomo(int geracao, Cromossomo cromossomo) { var aux_list = _list; foreach (var movimento in cromossomo.movimentosValidos) { aux_list[movimento.linha][movimento.coluna] = '$'; } Console.WriteLine(); Console.WriteLine($"Melhor Cromossomo da geração: {geracao} - Caminho: {printaCaminho(cromossomo)}- Aptidão: {Math.Round(cromossomo.peso, 2)}"); foreach (var item in aux_list) { for (int i = 0; i < item.Length; i++) { if (item[i] == '$') { Console.BackgroundColor = ConsoleColor.Red; Console.Write($" {item[i]} "); Console.ResetColor(); } else { Console.Write($" {item[i]} "); } } Console.WriteLine(); } }
public static string printaCaminho(Cromossomo cromossomo) { string retorno = string.Empty; foreach (var item in cromossomo.movimentosValidos) { retorno += $"({item.linha},{item.coluna}) "; } return(retorno); }
public static string printaMovimentos(Cromossomo cromossomo) { string retorno = string.Empty; foreach (var item in cromossomo.movimentos) { retorno += $"{item} "; } return(retorno); }
public static bool jaVisitouPosicao(Cromossomo cromossomo, int linha, int coluna) { foreach (var item in cromossomo.movimentosValidos) { if (item.linha == linha && item.coluna == coluna) { return(true); } } return(false); }
public static double calculaAptidao(Cromossomo cromossomo, int caminhosLivres) { //percentual referente a quantidade de movimentos contra parede pelo agente double movimentosEmParedes = Math.Abs((((double)(caminhosLivres - cromossomo.movimentosEmParedes) / caminhosLivres)) * 0.3); //percentual referente a quantidade de movimentos invalidos (fora da matriz) double movimentosInvalidos = Math.Abs((((double)(caminhosLivres - cromossomo.movimentosInvalidos) / caminhosLivres)) * 0.6); //percentual referente a quantidade de movimentos em laçoes feitos double MovimentosJaVisitados = Math.Abs((((double)(caminhosLivres - cromossomo.MovimentosJaVisitados) / caminhosLivres)) * 0.1); //percentual referente aos movimentos validos double MovimentosValidos = Math.Abs((((double)(caminhosLivres - cromossomo.movimentosValidos.Count) / caminhosLivres))); return(Math.Abs((1 - (movimentosEmParedes + movimentosInvalidos + MovimentosJaVisitados)) + (1 - MovimentosValidos))); }
public static bool encontrouImpedimento(Cromossomo cromossomo, int linha, int coluna) { bool retorno = false; if (iraSairDaMatriz(linha, coluna)) { cromossomo.movimentosInvalidos++; return(true); } if (_list[linha][coluna] == '1') { cromossomo.movimentosEmParedes++; retorno = true; } if (jaVisitouPosicao(cromossomo, linha, coluna)) { cromossomo.MovimentosJaVisitados++; } return(retorno); }
static void Main(string[] args) { int populacao = 120; int geracoes = 10; bool printa = true; string caminho = @"C:\Users\mathe\Desktop\IA\T1201902_arquivosDeEntrada\labirinto4_20.txt"; #if !DEBUG bool entrada = true; while (entrada) { try { Console.WriteLine(" - Informe o caminho do arquivo de entrada."); caminho = Console.ReadLine(); Console.WriteLine(" - Informe o tamanho da população."); int.TryParse(Console.ReadLine(), out populacao); Console.WriteLine(" - Informe o número de gerações"); int.TryParse(Console.ReadLine(), out geracoes); if (!File.Exists(caminho)) { throw new ArgumentException("Caminho não encotrado."); } entrada = false; } catch { Console.Clear(); Console.WriteLine(" - Erro encontrado, reinsira as entradas."); } } #endif leArquivoEntrada(caminho); List <Cromossomo> cromossomos = new List <Cromossomo>(); int caminhosLivres = retornaCaminhosLivres(); printaLabirinto(printa); Random rand = new Random(); bool agenteEncontrouSaida = false; int count = 0; while (count < geracoes && !agenteEncontrouSaida) { if (count == 0) //gera população inicial { cromossomos = geraPrimeiraGeracaoCromossomos(rand, populacao, caminhosLivres); } else //etapa de seleção { List <Cromossomo> novaGeracao = new List <Cromossomo>(); //elitismo var melhoresCromossomos = cromossomos.OrderByDescending(x => x.peso).ToList(); novaGeracao.Add(melhoresCromossomos[0]); //torneio - cruzamento - mutação while (novaGeracao.Count != populacao) { //seleção pai int pai1 = 0, pai2 = 0; while (pai1 == pai2) { pai1 = rand.Next(0, melhoresCromossomos.Count); pai2 = rand.Next(0, melhoresCromossomos.Count); } Cromossomo pai; if (melhoresCromossomos[pai1].peso > melhoresCromossomos[pai2].peso) { pai = melhoresCromossomos[pai1]; } else { pai = melhoresCromossomos[pai2]; } //seleção mãe int mae1 = 0, mae2 = 0; while (mae1 == mae2) { mae1 = rand.Next(0, melhoresCromossomos.Count); mae2 = rand.Next(0, melhoresCromossomos.Count); } Cromossomo mae; if (melhoresCromossomos[mae1].peso > melhoresCromossomos[mae2].peso) { mae = melhoresCromossomos[mae1]; } else { mae = melhoresCromossomos[mae2]; } //crossover 2 pontos Cromossomo filho1 = new Cromossomo(); Cromossomo filho2 = new Cromossomo(); int metadePai = pai.movimentos.Count / 3; int metadeMae = mae.movimentos.Count / 3; //filho 1 for (int j = 0; j < metadePai; j++) { filho1.movimentos.Add(pai.movimentos[j]); } for (int j = metadeMae; j < (metadeMae * 2); j++) { filho1.movimentos.Add(mae.movimentos[j]); } for (int j = (metadePai * 2); j < pai.movimentos.Count; j++) { filho1.movimentos.Add(pai.movimentos[j]); } //filho 2 for (int j = 0; j < metadeMae; j++) { filho2.movimentos.Add(mae.movimentos[j]); } for (int j = metadePai; j < (metadePai * 2); j++) { filho2.movimentos.Add(pai.movimentos[j]); } for (int j = (metadeMae * 2); j < mae.movimentos.Count; j++) { filho2.movimentos.Add(mae.movimentos[j]); } //Mutação - muta 3 movimento de cada cromossomo filho gerado int cromossomoMutar = 0; cromossomoMutar = rand.Next(0, melhoresCromossomos.FirstOrDefault().movimentos.Count - 1); filho1.movimentos[cromossomoMutar] = rand.Next(0, 9); cromossomoMutar = rand.Next(0, melhoresCromossomos.FirstOrDefault().movimentos.Count - 1); filho2.movimentos[cromossomoMutar] = rand.Next(0, 9); //garantir que a proxima população o mesmo tamanho da atual if (novaGeracao.Count < populacao) { novaGeracao.Add(filho1); } if (novaGeracao.Count < populacao) { novaGeracao.Add(filho2); } } //substituo a geração antiga pela nova cromossomos = novaGeracao; } foreach (var item in cromossomos) { //Coloca o agente na posição inicial Agente agente = new Agente() { posicao = new Posicao() { coluna = 0, linha = 0 } }; foreach (var movimento in item.movimentos) { if (movimento == 1) //direita { if (!encontrouImpedimento(item, agente.posicao.linha, agente.posicao.coluna + 1)) //tem parede? ou to no boundary? { agente.posicao.coluna = agente.posicao.coluna + 1; item.movimentosValidos.Add(new Posicao() { coluna = agente.posicao.coluna, linha = agente.posicao.linha }); if (encontrouSaida(agente.posicao.linha, agente.posicao.coluna)) { agenteEncontrouSaida = true; item.encontrouSaida = true; break; } } } else if (movimento == 2) //esquerda { if (!encontrouImpedimento(item, agente.posicao.linha, agente.posicao.coluna - 1)) //tem parede? ou to no boundary? { agente.posicao.coluna = agente.posicao.coluna - 1; item.movimentosValidos.Add(new Posicao() { coluna = agente.posicao.coluna, linha = agente.posicao.linha }); if (encontrouSaida(agente.posicao.linha, agente.posicao.coluna)) { agenteEncontrouSaida = true; item.encontrouSaida = true; break; } } } else if (movimento == 3) //cima { if (!encontrouImpedimento(item, agente.posicao.linha - 1, agente.posicao.coluna)) //tem parede? ou to no boundary? { agente.posicao.linha = agente.posicao.linha - 1; item.movimentosValidos.Add(new Posicao() { coluna = agente.posicao.coluna, linha = agente.posicao.linha }); if (encontrouSaida(agente.posicao.linha, agente.posicao.coluna)) { agenteEncontrouSaida = true; item.encontrouSaida = true; break; } } } else if (movimento == 4) //baixo { if (!encontrouImpedimento(item, agente.posicao.linha + 1, agente.posicao.coluna)) //tem parede? ou to no boundary? { agente.posicao.linha = agente.posicao.linha + 1; item.movimentosValidos.Add(new Posicao() { coluna = agente.posicao.coluna, linha = agente.posicao.linha }); if (encontrouSaida(agente.posicao.linha, agente.posicao.coluna)) { agenteEncontrouSaida = true; item.encontrouSaida = true; break; } } } else if (movimento == 5) //cima_direita { if (!encontrouImpedimento(item, agente.posicao.linha - 1, agente.posicao.coluna + 1)) //tem parede? ou to no boundary? { agente.posicao.linha = agente.posicao.linha - 1; agente.posicao.coluna = agente.posicao.coluna + 1; item.movimentosValidos.Add(new Posicao() { coluna = agente.posicao.coluna, linha = agente.posicao.linha }); if (encontrouSaida(agente.posicao.linha, agente.posicao.coluna)) { agenteEncontrouSaida = true; item.encontrouSaida = true; break; } } } else if (movimento == 6) //cima_esquerda { if (!encontrouImpedimento(item, agente.posicao.linha - 1, agente.posicao.coluna - 1)) //tem parede? ou to no boundary? { agente.posicao.linha = agente.posicao.linha - 1; agente.posicao.coluna = agente.posicao.coluna - 1; item.movimentosValidos.Add(new Posicao() { coluna = agente.posicao.coluna, linha = agente.posicao.linha }); if (encontrouSaida(agente.posicao.linha, agente.posicao.coluna)) { agenteEncontrouSaida = true; item.encontrouSaida = true; break; } } } else if (movimento == 7) //baixo_direita 7 { if (!encontrouImpedimento(item, agente.posicao.linha + 1, agente.posicao.coluna + 1)) //tem parede? ou to no boundary? { agente.posicao.linha = agente.posicao.linha + 1; agente.posicao.coluna = agente.posicao.coluna + 1; item.movimentosValidos.Add(new Posicao() { coluna = agente.posicao.coluna, linha = agente.posicao.linha }); if (encontrouSaida(agente.posicao.linha, agente.posicao.coluna)) { agenteEncontrouSaida = true; item.encontrouSaida = true; break; } } } else if (movimento == 8) //baixo_esquerda 8 { if (!encontrouImpedimento(item, agente.posicao.linha + 1, agente.posicao.coluna - 1)) //tem parede? ou to no boundary? { agente.posicao.linha = agente.posicao.linha + 1; agente.posicao.coluna = agente.posicao.coluna - 1; item.movimentosValidos.Add(new Posicao() { coluna = agente.posicao.coluna, linha = agente.posicao.linha }); if (encontrouSaida(agente.posicao.linha, agente.posicao.coluna)) { agenteEncontrouSaida = true; item.encontrouSaida = true; break; } } } } item.peso = calculaAptidao(item, caminhosLivres); if (agenteEncontrouSaida) { break; } } printaGeracao(count, cromossomos); var melhor = (from cromossomo in cromossomos orderby cromossomo.encontrouSaida descending, cromossomo.peso descending select cromossomo).FirstOrDefault(); printaMelhorCromossomo(count, melhor); Console.WriteLine(); Console.WriteLine(); //Thread.Sleep(1000); count++; } // Keep the console window open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); }