//cria uma popula��o com indiv�duos aleat�ria public Populacao(int numGenes, int tamPop) { tamPopulacao = tamPop; individuos = new Individuo[tamPop]; for (int i = 0; i < individuos.Length; i++) { individuos[i] = new Individuo(numGenes); } }
// Realiza o crossover de 1 ponto public static Individuo[] crossover(Individuo individuo1, Individuo individuo2) { Random r = new Random(); bool pontoCerto = false; int pontoCorte1 = 0; //sorteia o ponto de corte while (!pontoCerto) { pontoCorte1 = r.Next(individuo1.Genes.Length); string tempo = individuo1.Genes.Substring(pontoCorte1, 1); if (tempo.matches("[A-Z\\s]")) { pontoCerto = true; } } //pega os genes dos pais string genePai1 = individuo1.Genes; string genePai2 = individuo2.Genes; Individuo[] filhos = new Individuo[2]; string geneFilho1; string geneFilho2; //Gera o primeiro filho. geneFilho1 = genePai1.Substring(0, pontoCorte1 + 1); geneFilho1 += genePai2.Substring(pontoCorte1 + 1, genePai1.Length - (pontoCorte1 + 1)); //Gera o segundo filho. geneFilho2 = genePai2.Substring(0, pontoCorte1 + 1); geneFilho2 += genePai1.Substring(pontoCorte1 + 1, genePai2.Length - (pontoCorte1 + 1)); //cria o novo indiv�duo com os genes dos pais filhos[0] = new Individuo(geneFilho1); filhos[1] = new Individuo(geneFilho2); return filhos; }
//coloca um indiv�duo em uma certa posi��o da popula��o public virtual void setIndividuo(Individuo individuo, int posicao) { individuos[posicao] = individuo; }
public static Individuo[] selecaoTorneio(Populacao populacao) { Random r = new Random(); Populacao populacaoIntermediaria = new Populacao(3); //seleciona 3 indiv�duos aleat�riamente na popula��o populacaoIntermediaria.Individuo = populacao.getIndivduo(r.Next(populacao.TamPopulacao)); populacaoIntermediaria.Individuo = populacao.getIndivduo(r.Next(populacao.TamPopulacao)); populacaoIntermediaria.Individuo = populacao.getIndivduo(r.Next(populacao.TamPopulacao)); //ordena a popula��o populacaoIntermediaria.ordenaPopulacao(); Individuo[] pais = new Individuo[2]; //seleciona os 2 melhores deste popula��o pais[0] = populacaoIntermediaria.getIndivduo(0); pais[1] = populacaoIntermediaria.getIndivduo(1); return pais; }
public static Populacao novaGeracao(Populacao populacao, bool elitismo) { Random r = new Random(); //nova popula��o do mesmo tamanho da antiga Populacao novaPopulacao = new Populacao(populacao.TamPopulacao); //se tiver elitismo, mant�m o melhor indiv�duo da gera��o atual if (elitismo) { novaPopulacao.Individuo = populacao.getIndivduo(0); } //insere novos indiv�duos na nova popula��o, at� atingir o tamanho m�ximo while (novaPopulacao.NumIndividuos < novaPopulacao.TamPopulacao) { //seleciona os 2 pais por torneio Individuo[] pais = selecaoTorneio(populacao); Individuo[] filhos = new Individuo[2]; //verifica a taxa de crossover, se sim realiza o crossover, se n�o, mant�m os pais selecionados para a pr�xima gera��o if (r.NextDouble() <= taxaDeCrossover) { filhos = crossover(pais[1], pais[0]); } else { filhos[0] = new Individuo(pais[0].Genes); filhos[1] = new Individuo(pais[1].Genes); } //adiciona os filhos na nova gera��o novaPopulacao.Individuo = filhos[0]; novaPopulacao.Individuo = filhos[1]; } //ordena a nova popula��o novaPopulacao.ordenaPopulacao(); return novaPopulacao; }
private void Awake() { _individuo = this.gameObject.GetComponent <Individuo>(); }
static void Main(string[] args) { List <Indicadores> ResultadoTestes = new List <Indicadores>(); List <Individuo> individuos = new List <Individuo>(); string[] database = CarregarDataBase(); individuos = SeparadorDeAtributos(database); int quantidadeIndividuos = individuos.Count(); int K = 33; Console.WriteLine("Iniciando... \n Database: Iris utilizando K Alternado."); for (int contador = 1; contador <= 30; contador++) { List <Individuo> ListSet = new List <Individuo>(); List <Individuo> ListVer = new List <Individuo>(); List <Individuo> ListVir = new List <Individuo>(); List <Individuo> Z1 = new List <Individuo>(); List <Individuo> Z2 = new List <Individuo>(); List <Individuo> Z3 = new List <Individuo>(); int acertos = 0, erros = 0; double taxaDeAcerto = 0; #region Divisão por Classe (Base pra dividir os Z's) foreach (var indv in individuos) { if (indv.classe == "Iris-setosa") { ListSet.Add(indv); continue; } if (indv.classe == "Iris-virginica") { ListVir.Add(indv); continue; } if (indv.classe == "Iris-versicolor") { ListVer.Add(indv); continue; } } #endregion #region Divisão dos Z's Random randNum = new Random(); Individuo AuxAdd; #region [Setosa para Z1] while (Z1.Count() < 13) { AuxAdd = ListSet.ElementAt(randNum.Next(ListSet.Count() - 1)); if (!AuxAdd.usado) { AuxAdd.usado = true; Z1.Add(AuxAdd); } } #endregion #region [Setosa para Z2] while (Z2.Count() < 13) { AuxAdd = ListSet.ElementAt(randNum.Next(ListSet.Count() - 1)); if (!AuxAdd.usado) { AuxAdd.usado = true; Z2.Add(AuxAdd); } } #endregion #region [Setosa para Z3] while (Z3.Count() < 24) { AuxAdd = ListSet.Where(c => c.usado == false).First(); AuxAdd.usado = true; Z3.Add(AuxAdd); } #endregion #region [Versicolor para Z1] while (Z1.Count() < 26) { AuxAdd = ListVer.ElementAt(randNum.Next(ListVer.Count() - 1)); if (!AuxAdd.usado) { AuxAdd.usado = true; Z1.Add(AuxAdd); } } #endregion #region [Versicolor para Z2] while (Z2.Count() < 26) { AuxAdd = ListVer.ElementAt(randNum.Next(ListVer.Count() - 1)); if (!AuxAdd.usado) { AuxAdd.usado = true; Z2.Add(AuxAdd); } } #endregion #region [Versicolor para Z3] while (Z3.Count() < 48) { AuxAdd = ListVer.Where(c => c.usado == false).First(); AuxAdd.usado = true; Z3.Add(AuxAdd); } #endregion #region [Virginica para Z1] while (Z1.Count() < 38) { AuxAdd = ListVir.ElementAt(randNum.Next(ListVir.Count() - 1)); if (!AuxAdd.usado) { AuxAdd.usado = true; Z1.Add(AuxAdd); } } #endregion #region [Virginica para Z2] while (Z2.Count() < 38) { AuxAdd = ListVir.ElementAt(randNum.Next(ListVir.Count() - 1)); if (!AuxAdd.usado) { AuxAdd.usado = true; Z2.Add(AuxAdd); } } #endregion #region [Virginica para Z3] while (Z3.Count() < 74) { AuxAdd = ListVir.Where(c => c.usado == false).First(); AuxAdd.usado = true; Z3.Add(AuxAdd); } #endregion #endregion string[] classeObtida = ClassificadorDeAmostras(Z1, Z2, K); int a = 0; Individuo auxTroca = null, auxTroca2 = null; #region Verifica os errados em Z1 foreach (var metricaAcertos in Z1) { if (metricaAcertos.classe != classeObtida[a]) { metricaAcertos.errado = true; } //indicador de posição da classe - Ou seja, auxiliar do Foreach a++; } #endregion #region [Troca o que tá errado em Z1 com algum Z2 com classe igual] while (Z1.Any(e => e.errado == true)) { auxTroca = Z1.Where(e => e.errado == true).First(); auxTroca2 = Z2.Where(c => c.classe == auxTroca.classe).First(); Z1.Remove(auxTroca); Z2.Remove(auxTroca2); auxTroca.trocado = true; auxTroca.errado = false; auxTroca2.trocado = true; Z1.Add(auxTroca2); Z2.Add(auxTroca); } #endregion #region [Limpeza das Variaveis para a "Próxima Rodada"] foreach (var limpZ1 in Z1) { limpZ1.trocado = false; limpZ1.usado = false; } foreach (var limpZ2 in Z2) { limpZ2.trocado = false; limpZ2.usado = false; } #endregion //Testa Z3 com Z2 e retorna os resultados. classeObtida = ClassificadorDeAmostras(Z3, Z2, K); #region Verifica os acertos em Z3 a = 0; foreach (var metricaAcertos in Z3) { if (metricaAcertos.classe == classeObtida[a]) { acertos++; } else { erros++; } //indicador de posição da classe - Ou seja, auxiliar do Foreach a++; } #endregion #region [Grava a quantidade de acertos para fazer os relatorios depois] taxaDeAcerto = (acertos * 100) / Z3.Count(); Indicadores indicador = new Indicadores(acertos, erros, taxaDeAcerto); ResultadoTestes.Add(indicador); #endregion Console.WriteLine("Rodada " + contador + "...\n" + "Taxa de Acerto: " + taxaDeAcerto + "% " + "K:" + K); foreach (var setarIndividuos in individuos) { setarIndividuos.usado = false; } ListSet = null; ListVer = null; ListVir = null; Z1 = null; Z2 = null; Z3 = null; K--; } Console.WriteLine("... \n..."); #region [Calculo Final] double soma = 0, media, desvioPadrao; foreach (var baseDeCalculo in ResultadoTestes) { soma += baseDeCalculo.taxaDeAcerto; } media = soma / ResultadoTestes.Count(); soma = 0; foreach (var baseDeCalculo in ResultadoTestes) { soma += Math.Pow((baseDeCalculo.taxaDeAcerto - media), 2); } desvioPadrao = Math.Sqrt(soma / ResultadoTestes.Count()); Console.WriteLine("Media:" + media); Console.WriteLine("Desvio Padrão:" + desvioPadrao); #endregion Console.ReadKey(); }
//Algoritmo genético: private void GeneticAlgorithm() { Random rand = new Random((int)DateTime.Now.Ticks); // gerador de num. aleatório int iterationCount = 0; //Inicializa variável que armazena o valor da geração atual int noProgressIterations = 0; double bestDist = 0; bool allEqual = false; //Inicia a variável de convergência em falso Path.Clear(); //Limpa a lista caminho Population.Clear(); //Limpa a lista de população // get population size try { //Obtém o número de população NPop = Math.Max(10, Math.Min(100000, int.Parse(populationSizeBox.Text))); } catch { //Se anteriormente houve uma exceção, estabelecer população em um valor constante NPop = 100; } //get iterations num. try { //Obtém o número de gerações NGer = Math.Max(100, Math.Min(1000000000, int.Parse(iterationsBox.Text))); } catch { //Se anteriormente houve uma exceção, estabelecer número de gerações em um valor constante NGer = 100; } try { //Obtém chance de mutação NMut = Math.Max(0, Math.Min(100, double.Parse(mutationChanceBox.Text))); } catch { //Se anteriormente houve uma exceção, estabelecer chance de mutação em um valor constante NMut = 0; } //Atualiza itens da interface, que estão em outra Thread this.Invoke((MethodInvoker) delegate { //Atualiza valores das textbox: //--------------------------------------------- populationSizeBox.Text = NPop.ToString(); iterationsBox.Text = NGer.ToString(); mutationChanceBox.Text = NMut.ToString(); //--------------------------------------------- //Impede a alteração dos valores das textbox até o término da execução: //--------------------------------------------- iterationsBox.ReadOnly = true; populationSizeBox.ReadOnly = true; mutationChanceBox.ReadOnly = true; citiesCountBox.ReadOnly = true; //--------------------------------------------- }); //Enquanto i for menor que o valor populacional... for (int i = 0; i < NPop; i++) { Individuo indv = new Individuo(Map, rand); //Criar um novo indivíduo com genes aleatórios Population.Add(indv); //Adicionar o indivíduo à população } //Enquanto não tiver atingido o número máximo de gerações... while (iterationCount < NGer) { //Ordena os indivíduos da população de acordo com seu fitness (menor distância do percurso) Population.Sort((x, y) => x.distance.CompareTo(y.distance)); //Cria uma lista para os piores indivíduos da população (1/3) List <Individuo> PopulationWorst = new List <Individuo>(); //Cria uma lista para os melhores indívuos da população (2/3) //Esses indivíduos serão os pais da nova geração List <Individuo> PossibleParents = new List <Individuo>(); //Calcular o valor aproximado de dois terços da população int parentFraction = (Population.Count * 2) / 3; //Povoar a lista dos piores indivíduos com os piores indivíduos (1/3 da população) PopulationWorst = Population.GetRange(parentFraction, NPop - parentFraction); //Povoar a lista dos possíveis pais com os melhores indivíduos (2/3 da população) PossibleParents = Population.GetRange(0, parentFraction); //Atualizar a população atual para conter apenas os melhores indivíduos da atualidade Population = Population.GetRange(0, parentFraction); //Cria uma lista para aqueles que já foram pais List <Individuo> Parents = new List <Individuo>(); //Cria uma lista para os filhos que serão gerados List <Individuo> Children = new List <Individuo>(); //Enquanto o número de filhos for menor do que a quantidade de piores indivíduos da população... while (Children.Count < PopulationWorst.Count) { int parentCount = PossibleParents.Count; //Obter o número de indivíduos que ainda podem ser pais if (parentCount > 1) //Se o número de possíveis pais for maior que 1 { int randFather; //Posição da população correspondente ao pai int randMother; //Posição da população correspondente à mãe do { randFather = rand.Next(parentCount); //Gera uma posição aleatória na população para o pai randMother = rand.Next(parentCount); //Gera uma posição aleatória na população para a mãe }while (randFather == randMother); //Se as posições de pai e mãe forem as mesmas, repetir o processo //Obtém o indivíduo pai correspondente à posição da população gerada aleatoriamente Individuo father = PossibleParents[randFather]; //Obtém o indivíduo mãe correspondente à posição da população gerada aleatoriamente Individuo mother = PossibleParents[randMother]; Parents.Add(father); //Adiciona o pai à lista daqueles que já tiveram filhos Parents.Add(mother); //Adiciona a mãe à lista daqueles que já tiveram filhos PossibleParents.Remove(father); //Remove o pai da lista de possíveis pais PossibleParents.Remove(mother); //Remove a mãe da lista de possíveis pais Individuo child; //Declara o indivíduo filho child = Individuo.Offspring(father, mother, rand); //Gera o filho de acordo com os genes do pai e da mãe Children.Add(child); //Adiciona a criança à lista de filhos } else { //Se não houver mais pais mas ainda faltar filhos Individuo new_child = new Individuo(Map, rand); Children.Add(new_child); //Adicione um filho que será um novo indivíduo aleatório } } //Adicione à lista de filhos os piores indivíduos da população //(É possível que existam filhos piores do que os piores indivíduos da população anterior) Children.AddRange(PopulationWorst); //Ordenar a lista de filhos de acordo com a função de fitness (distância do percurso) Children.Sort((x, y) => x.distance.CompareTo(y.distance)); //Manter apenas os melhores indivíduos entre essa população (1/3 do total) //Children = Children.Take<Individuo>(NPop - parentFraction).ToList(); Children = Children.GetRange(0, NPop - parentFraction); //Adiciona esses filhos novamente à população total Population.AddRange(Children); if (NMut > 0) //Se a chance de mutação for maior que 0 { //Para cada indivíduo na população... foreach (Individuo indv in Population) { //Se esse indivíduo for o melhor indivíduo da população atual... if (indv == Population.First()) { //Passe para o próximo indivíduo, esse aqui é muito bom para sofrer mutação //Just too good for it continue; } //Obtém um número aleatório entre 0.0 e 1.0 double chance = rand.NextDouble(); //Multiplicar esse número por 100, para colocá-lo na faixa de 0.0 à 100.0 chance *= 100; //Se o valor estiver abaixo do valor de mutação definido pelo usuário... if (chance <= NMut) { indv.Mutate(rand); //Realizar a mutação no indivíduo indv.RecalculateDistance(); //Recalcular o fitness desse indivíduo } } } iterationCount++; //Incrementa o valor da geração atual this.Invoke((MethodInvoker) delegate { //Atualiza o valor do textbox que exibe a melhor distância pathLengthBox.Text = Population[0].distance.ToString("#0.0"); //Atualiza o valor da label, que está em outra Thread label6.Text = iterationCount.ToString(); }); if (bestDist <= Population[0].distance) { noProgressIterations++; } else { noProgressIterations = 0; } //Define que a melhor distância é aquela do indivíduo na primeira posição bestDist = Population[0].distance; //Se todos os indivíduos da população tiverem esse mesmo valor, todos são iguais allEqual = Population.All(o => o.distance == bestDist); if (allEqual) { ResetarPopulacao(Population, rand); } else if (noProgressIterations >= Math.Max(NGer * 0.025, 20)) { if (noProgressIterations > NGer * 0.2) { //Early Convergence break; } else { ResetarPopulacao(Population, rand); } } } //Reordena a população de acordo com a função de fitness (distância do percurso) //Population.Sort((x, y) => x.distance.CompareTo(y.distance));; //Declara uma matriz de Número de cidades x 2 que armazenará o melhor caminho double[,] path = new double[NCities, 2]; //Adiciona os genes do melhor indivíduo da população à lista do melhor caminho Path.AddRange(Population[0].genes); //Converte essa lista em uma matriz que será utilizada para desenhar o caminho path = ListToMatrix(Path); //Obtém as coordenadas do ponto de início/fim, que correspondem ao primeiro item do caminho double[,] start_end = new double[, ] { { Path[0].X, Path[0].Y } }; //atualiza mapa com o caminho a ser percorrido: mapControl.UpdateDataSeries("path", path); //Atualiza o mapa com o ponto de início e fim mapControl.UpdateDataSeries("start_end", start_end); //calcula o caminho total percorrido: double caminho = Population[0].distance; pathLengthBox.Invoke((MethodInvoker) delegate { //Atualiza o valor do textbox que exibe a melhor distância pathLengthBox.Text = caminho.ToString("#0.0"); }); this.Invoke((MethodInvoker) delegate { //Permite que as textbox sejam modificadas novamente iterationsBox.ReadOnly = false; populationSizeBox.ReadOnly = false; mutationChanceBox.ReadOnly = false; citiesCountBox.ReadOnly = false; }); //Anula a Thread que executa o algoritmo genético GA_Thread = null; }