def __init__(self): self.taxaCrossover = 0.8 self.taxaMutacao = 0 self.geracoes = 100 self.numPopulacao = 100 self.populacao = Populacao(self.numPopulacao)
def main(): # guarda historico de todas as geracoes populacoes = [] # populacao inicial populacaoInicial = AlgoritmoGenetico.geraPopulacaoInicial() populacoes.append(Populacao(populacaoInicial)) # arrays para plotagem do grafico historicoMelhorFitness = [] historicoFitnessMedio = [] # executa algoritmo genetico ate um numero maximo de geracoes definido nos parametros do programa for k in range(Variaveis.numMaximoGeracoes): # seleciona pais para cruzamento pais = AlgoritmoGenetico.selecaoDePaisTorneio(populacaoInicial, 5, len(populacaoInicial)) # crossover e mutacao descendentes = AlgoritmoGenetico.crossover(pais) # imprime no console informacoes da geracao atual for descendente in descendentes: print("geração: " + str(k) + " genes: " + descendente.getGenes() + " - fitness: " + str(descendente.fitness())) # define a populacao de descendentes como principal e reinicia o processo populacaoInicial = descendentes # guarda historico da geracao populacoes.append(Populacao(descendentes)) # exibicao no console de informacoes sobre a execucao do programa # print("############### POPULACAO FINAL ###############") for fim in populacaoInicial: print("fim: " + fim.getGenes() + " - fitness: " + str(fim.fitness())) print("############### MELHOR FITNESS - MEDIA ###############") for pop in populacoes: historicoMelhorFitness.append( pop.calculaFitnessMedioEMelhorFitness()[0]) historicoFitnessMedio.append( pop.calculaFitnessMedioEMelhorFitness()[1]) print(pop.calculaFitnessMedioEMelhorFitness()) # FIM - exibicao no console de informacoes sobre a execucao do programa # # plotagem do grafico # fig, axs = plt.subplots(1, 1, constrained_layout=True) axs.plot(historicoMelhorFitness) axs.plot(historicoFitnessMedio) axs.set_title('População total: ' + str(Variaveis.tamanhoPopulacao) + ' - Gerações: ' + str(Variaveis.numMaximoGeracoes)) axs.set_xlabel('geração') axs.set_ylabel('Fitness') axs.legend(['Melhor Fitness', 'Fitness Médio'], loc='lower right') axs.xaxis.set_major_locator(MaxNLocator(integer=True)) plt.show()
def __init__(self): self.taxaCrossover = 0.8 self.taxaMutacao = 0.1 self.geracoes = 100 self.numPopulacao = 100 self.qtdElite = 30 self.qtdCidades = 10 self.populacao = Populacao(self.numPopulacao)
def __init__(self, taxaCrossover, taxaMutacao, geracoes, numPopulacao, limiteEspacos, gastoMaximo, qtdElite): self.taxaCrossover = taxaCrossover self.taxaMutacao = taxaMutacao self.geracoes = geracoes self.numPopulacao = numPopulacao self.qtdElite = qtdElite self.melhorSolucao = None self.populacao = Populacao(numPopulacao, limiteEspacos, gastoMaximo) self.melhorSolucao = self.populacao.listaDeIndividuos[0]
def __init__(self, taxaCrossover, taxaMutacao, geracoes, tamanhoPopulacao, tamanhoCromossomo): self.tamaanhoCromossomo = tamanhoCromossomo self.taxaCrossover = taxaCrossover self.taxaMutacao = taxaMutacao self.geracoes = geracoes self.tamanhoPopulacao = tamanhoPopulacao self.tamanhoCromossomo = tamanhoCromossomo self.populacao = Populacao(taxaCrossover, taxaMutacao, tamanhoPopulacao, tamanhoCromossomo) self.populacao.calculaFitness() self.populacao.calculaRangeRoleta()
def generatePopulacaoReal(numIndividuos: int, taxaCrossover: float, taxaMutacao: float) -> Populacao: '''Cria a população baseado no número de indivíduos e número de bits.''' populacao: Populacao = Populacao(None, taxaCrossover, taxaMutacao) populacao.criaIndividuos(numIndividuos) return populacao
def generateNewGeracoes(populacao: Populacao, numGeracoes: int) -> dict: '''Gera as novas espécies baseado em diversos fatores tais como: crossover entre pais e mutações pegando seu melhor valor de aptidão para cada geração''' bestEspeciesByGeneration: dict = {} for i in range(numGeracoes): # Aplica o crossover entre os pais baseado no seleção de torneio e valor de aptidão de cada invíduo da espécie teveCrossover: bool = populacao.aplicaCrossover() # Aplica a mutação para cada invidíduo da população teveMutacao: bool = populacao.aplicaMutacao(i + 1, numGeracoes) # Pega o melhor valor de aptidão dentre todos da espécies e armazena bestEspeciesByGeneration[i + 1] = copy.deepcopy( populacao.bestAptidaoIndividuo()) return bestEspeciesByGeneration
def main(): ans = [] for tr in [1, 2, 3]: temp = [] for i in range(50): a = Populacao() a.generateSolution(roleta=True, tiporecomb=tr) temp.append(a.ger) print(temp) ans.append(temp) # print(ans) # print(mean(ans)) # print(std(ans)) # r1 = [762, 411, 690, 779, 293, 488, 456, 527, 566, 641] # r2 = [602, 333, 288, 442, 514, 307, 423, 495, 313, 467] # r3 = [596, 501, 531, 799, 686, 998, 542, 441, 819, 695] for i in ans: print(shapiro(i)) print() cruzamentos = {0: "Aleatorio", 1: "CX", 2: "PMX"} # # for i in [r1, r2, r3]: # # print(ttest_ind(i)) # print(ttest_ind(r2, r3)) pairs = list(combinations(list(range(3)), 2)) for p in pairs: print(f't_test entre {cruzamentos[p[0]]} e {cruzamentos[p[1]]}') print(ttest_ind(ans[p[0]], ans[p[1]])) print()
def evoluir(self): ''' Método responsável por controlar toda a execução do algoritmo genético, incluindo os cruzamentos e a mutação @return: a última população de cromossomos ''' retorno = [] self.__Populacao = Populacao(self.__tipoGenes, distribuido=self.__distribuido, maiorValor=self.__considMaiorAvaliacao) self.__Populacao.gerarPopulacao(self.__qntIndividuos) self.__Populacao.avaliarPopulacao(self.__funcaoAvaliacao) if self.__criterioSatisfacao != 0.0: resp, cromos = self.verCriterioTerminacao() Ger = 1 if self.__maxGeracoes == 0: while not resp: self.__Populacao.geraNovaPopulacao(self.__funcaoAvaliacao, self.__considMaiorAvaliacao) resp, cromos = self.verCriterioTerminacao() if self.__verboso: print "Indivíduos que alcançaram o critério de Satisfação:" for i in cromos: retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() elif self.__criterioSatisfacao != 0.0: while not resp and Ger <= self.__maxGeracoes: if self.__verboso: print "Geração:", Ger self.__Populacao.geraNovaPopulacao(self.__funcaoAvaliacao, self.__considMaiorAvaliacao) resp, cromos = self.verCriterioTerminacao() Ger += 1 if resp: if self.__verboso: print "Indivíduos que alcançaram o critério de Satisfação:" for i in cromos: retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() else: if self.__verboso: print "Indivíduos não alcançaram o critério de Satisfação!" if self.__verboso: print "A última população foi:" for i in self.__Populacao.getIndividuos(): retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() else: for Ger in range(self.__maxGeracoes): if self.__verboso: print "Geração:", Ger self.__Populacao.geraNovaPopulacao(self.__funcaoAvaliacao, self.__considMaiorAvaliacao, self.__retCromo) if self.__verboso: print "A última população foi:" for i in self.__Populacao.getIndividuos(): retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() return retorno
class AlgoritmoGenetico(): def __init__(self): self.taxaCrossover = 0.8 self.taxaMutacao = 0 self.geracoes = 100 self.numPopulacao = 100 self.populacao = Populacao(self.numPopulacao) def executarAG(self): print('GERAÇÃO 1') self.populacao.calcularRangeRoleta() self.populacao.printPopulacao() print('\n') for i in range(self.geracoes - 1): print('GERAÇÃO {}'.format(i + 2)) self.populacao.setListaDeIndividuos(self.crossover()) self.mutacao() self.populacao.fitnessTotal = 0 self.populacao.calcularFitness() self.populacao.mediaPopulacao = 0 self.populacao.calcularRangeRoleta() self.populacao.printPopulacao() print('\n\n') print('OS 10 MELHORES RESULTADOS: \n') for i in range(10): self.populacao.getListaDeIndividuos()[i].printCromossomo() print('Média de Aptidão da População: \n') print(self.populacao.getMediaPopulacao()) self.plotGraficos() ''' Sorteia número que irá escolher os pais na roleta para o crossover. ''' def roleta(self): selecaoRoleta = random() * 100 for individuo in self.populacao.getListaDeIndividuos(): faixaRoleta = individuo.getFaixaRoleta() if (selecaoRoleta >= faixaRoleta[0] and selecaoRoleta <= faixaRoleta[1]): return individuo return self.populacao.getListaDeIndividuos()[0] ''' Cruzamento entre dois pais para criação de dois filhos. ''' def crossover(self): novaGeracao = [] for i in range(int(self.numPopulacao / 2)): individuo_1 = self.roleta() individuo_2 = self.roleta() if (random() < self.taxaCrossover): pontoCorte = round(random() + len(individuo_1.getCromossomo())) filho_1 = individuo_2.getCromossomo( )[0:pontoCorte] + individuo_1.getCromossomo()[pontoCorte::] filho_2 = individuo_1.getCromossomo( )[0:pontoCorte] + individuo_2.getCromossomo()[pontoCorte::] filhos = [Individuo(), Individuo()] filhos[0].setCromossomo(filho_1) filhos[0].setGeracao(individuo_1.getGeracao()) filhos[1].setCromossomo(filho_2) filhos[1].setGeracao(individuo_1.getGeracao()) novaGeracao.append(filhos[0]) novaGeracao.append(filhos[1]) else: novaGeracao.append(individuo_1) novaGeracao.append(individuo_2) return novaGeracao def mutacao(self): for individuo in self.populacao.getListaDeIndividuos(): individuo.mutarBit(self.taxaMutacao) ''' FUNÇÕES DO GRÁFICO. ''' def funcao1(self, x): return 100 + math.fabs(x * math.sin(math.sqrt(math.fabs(x)))) def plotFuncao1(self): y = [] x = [] for individuo in self.populacao.getListaDeIndividuos(): i = individuo.getFenotipo() x.append(i) y.append(self.funcao1(i)) plt.plot(x, y, color='r', linewidth=2.0) def plotPop(self): x_populacao = [] y_populacao = [] for individuo in self.populacao.getListaDeIndividuos(): x_populacao.append(individuo.getFenotipo()) y_populacao.append(self.funcao1(individuo.getFenotipo())) plt.stem(x_populacao, y_populacao, use_line_collection=True) def plotGraficos(self): plt.title('Gerações', fontdict=None, loc='center', pad=None) self.plotFuncao1() self.plotPop() plt.show()
# parâmetros iniciais populacao = 200 geracoes = 1000000 prob_mutacao = 0.01 prob_crossover = 0.7 #loop de arquivos: for i in range(1, 6): # para o gráfico no relatório melhores = [] media = [] #inicia população p = Populacao(populacao, prob_mutacao, prob_crossover) p.iniciaPopulacao() # i = 0 #nome de arquivo nomeArq = 'arquivo' + str(i) + '.txt' print(datetime.datetime.now()) # gera arquivo de texto com dados de melhores / media j = 0 with open(nomeArq, 'w+') as f: # grava parametros no arquivo de texto f.write("Roleta+Roleta(original) Populacao: " + str(populacao) + " Geracoes: " + str(geracoes) + " Prob.Mutacao: " + str(prob_mutacao) + " Prob.Cross.: " + str(prob_crossover) + "\n") while (j < geracoes): # guarda o melhor indivíduo da geração atual no vetor estático 'melhores'
"C": 300, "Df": 25, "Ca": 1000, "Mg": 260, "Mn": 2.3, "P": 700, "Fe": 14, "Na": 2400, "Zn": 7 } produtos_ids = __io.load_products("Dataset/produtos.json") nutrientes_prod = __io.load_data("Dataset/dataset_formatado.csv") nutrientes_prod_dict = pd_to_dict(nutrientes_prod) populacao = Populacao(refeicoes, produtos_ids, dieta_kcal, npop, taxa_cruzamento, taxa_mutacao) log_pop = [] for ger_i in range(0, nger): populacao.avalia_pop(nutrientes_prod_dict, restricoes, penalidade=100) log_pop.append(gen_log(populacao)) melhor_indiv = populacao.get_melhor_indiv() pais = populacao.torneio() indiv_interm = populacao.cruzamento(pais, refeicoes, produtos_ids) populacao.substituir_pop(indiv_interm) populacao.exec_elitismo(melhor_indiv) print("=> Geração: " + str(ger_i + 1) + "/" + str(nger) + " -> Melhor solução encontrada até o momento: %.2f" % melhor_indiv.fitness, melhor_indiv.valida(nutrientes_prod_dict, restricoes), end=" \r")
class AlgoritmoGenetico: def __init__(self, taxaCrossover, taxaMutacao, geracoes, tamanhoPopulacao, tamanhoCromossomo): self.tamaanhoCromossomo = tamanhoCromossomo self.taxaCrossover = taxaCrossover self.taxaMutacao = taxaMutacao self.geracoes = geracoes self.tamanhoPopulacao = tamanhoPopulacao self.tamanhoCromossomo = tamanhoCromossomo self.populacao = Populacao(taxaCrossover, taxaMutacao, tamanhoPopulacao, tamanhoCromossomo) self.populacao.calculaFitness() self.populacao.calculaRangeRoleta() def executaAG(self): #populacao. print('executando AG') #for novas geracoes for i in range(self.geracoes): novosIndividuos = self.crossover() self.populacao.individuos = novosIndividuos self.mutacao() self.populacao.evoluir() self.populacao.printPopulacao() def roleta(self): numRoleta = random() * 100 for i in range(self.tamanhoPopulacao): if self.populacao.individuos[i].isInRange(numRoleta): return i return 0 def crossover(self): novosIndividuos = [] for i in range(int(self.tamanhoPopulacao / 2)): pai = self.populacao.individuos[self.roleta()] mae = self.populacao.individuos[self.roleta()] r = random() if (r < self.taxaCrossover): corte = round(random() * self.tamanhoCromossomo) cromF0 = pai.cromossomo[0:corte] + mae.cromossomo[corte::] cromF1 = mae.cromossomo[0:corte] + pai.cromossomo[corte::] filho0 = Individuo(self.tamanhoCromossomo) filho1 = Individuo(self.tamanhoCromossomo) filho0.cromossomo = cromF0 filho1.cromossomo = cromF1 novosIndividuos.append(filho0) novosIndividuos.append(filho1) else: novosIndividuos.append(pai) novosIndividuos.append(mae) return novosIndividuos def mutacao(self): for i in range(len(self.populacao.individuos)): self.populacao.individuos[i].mutatBit(self.taxaMutacao)
TAMANHO_POPULACAO = 100 # Função resposável por definir a função matemática que sera usada no algoritmo def f(x): return 5 * x**2 + 50 * x - 20 # 5x² + 50x - 20 # return x**3 - 4*x**3 + 4*x**2 + 10 # x³ - 4x³ + 4x² + 10 # return math.cos(3*x) + 3 # cos(3*x) + 3 plt.title('Gráfico do Fitness das gerações') plt.xlabel('Geração') plt.ylabel('Fitness') # inicializacao da populacao parametros: (TAMANHO_POPULACAO, TAMANHO_INDIVIDUO, POSSUI_MINIMO, FUNCAO_MATEMATICA) populacao = Populacao(TAMANHO_POPULACAO, TAMANHO_INDIVIDUO, False, f) populacao.inicializar() populacao.arrMelhoresIndividuoes.append(populacao.melhorIndividuo.fitness) while (populacao.contadorGeracao < 300): populacao.calcularFitness() populacao.selecao( 0.7 ) # o percentual se refere a quantidade de individuos que sobreviverao à selecao populacao.reproducao( 0.46 ) # o percentual se refere a quantidade de novos individuos gerados
class AlgoritmoGenetico(): def __init__(self): self.taxaCrossover = 0.8 self.taxaMutacao = 0.1 self.geracoes = 100 self.numPopulacao = 100 self.qtdElite = 30 self.qtdCidades = 10 self.populacao = Populacao(self.numPopulacao) def executarAG(self): print('GERAÇÃO 1') self.populacao.calcularRangeRoleta() self.populacao.printPopulacao() print('\n') for i in range(self.geracoes - 1): print('GERAÇÃO {}'.format(i + 2)) self.populacao.setListaDeIndividuos(self.elitista()) self.mutacao_PermutacaoDeElementos() self.populacao.fitnessTotal = 0 self.populacao.calcularFitness() self.populacao.mediaPopulacao = 0 self.populacao.calcularRangeRoleta() self.populacao.printPopulacao() print('\n\n') #self.printGrafico(self.populacao.x, self.populacao.y, [2,3,1,4,8,7,6,5,10,9], self.geracoes, self.populacao.getMediaPopulacao) ''' Sorteia número que irá escolher os pais na roleta para o crossover. ''' def roleta(self): selecaoRoleta = random() * 100 for individuo in self.populacao.getListaDeIndividuos(): faixaRoleta = individuo.getFaixaRoleta() if (selecaoRoleta >= faixaRoleta[0] and selecaoRoleta <= faixaRoleta[1]): return individuo return self.populacao.getListaDeIndividuos()[0] def elitista(self): self.populacao.setListaDeIndividuos( sorted(self.populacao.getListaDeIndividuos(), key=Individuo.getFitnessPercent)) novaGeracao = [] for i in range(self.qtdElite): novaGeracao.append(self.populacao.getListaDeIndividuos().pop()) return self.crossover_BaseadoEmOrdem(novaGeracao) ''' ''' def crossover_BaseadoEmOrdem(self, novaGeracao): for i in range(int(self.numPopulacao / 2)): individuo_1 = self.roleta() individuo_2 = self.roleta() if (random() < self.taxaCrossover): filho_1 = self.crossover(individuo_1.getCromossomo(), individuo_2.getCromossomo()) filho_2 = self.crossover(individuo_2.getCromossomo(), individuo_1.getCromossomo()) filhos = [Individuo(), Individuo()] filhos[0].setCromossomo(filho_1) filhos[0].setGeracao(individuo_1.getGeracao()) filhos[1].setCromossomo(filho_2) filhos[1].setGeracao(individuo_1.getGeracao()) novaGeracao.append(filhos[0]) novaGeracao.append(filhos[1]) else: novaGeracao.append(individuo_1) novaGeracao.append(individuo_2) return novaGeracao def crossover(self, individuo1, individuo2): mascara = [] for i in range(10): if (random() < 0.5): mascara.append('0') else: mascara.append('1') filho = [] listaAux = [] listaAuxOrdenada = [] for i in range(10): if (mascara[i] == '1'): filho.append(individuo1[i]) else: filho.append(0) listaAux.append(individuo1[i]) for i in range(len(individuo2)): if individuo2[i] in listaAux: listaAuxOrdenada.append(individuo2[i]) aux = 0 for i in range(10): if (filho[i] == 0): filho[i] = listaAux[aux] aux = aux + 1 return filho def mutacao_PermutacaoDeElementos(self): for individuo in self.populacao.getListaDeIndividuos(): individuo.mutacao(self.taxaMutacao) ''' FUNÇÕES DO GRÁFICO. ''' def printGrafico(self, x, y, ordem, geracao, media): plt.title(geracao, fontdict=None, loc='center', pad=None) self.printPontos(x, y) self.printPontoStart(x[0], y[0]) self.printCaminhos(x, y, ordem) plt.plot(media, color='b', linewidth=1.0) plt.show() def printPontos(self, x, y): plt.scatter(x, y, marker='o') def printPontoStart(self, x, y): plt.scatter(x, y, color='r', marker='o') def printCaminhos(self, x, y, ordem): x_c = [] y_c = [] for i in range(self.qtdCidades): x_c.append(x[ordem[i]]) y_c.append(y[ordem[i]]) plt.plot(x_c, y_c, color='r') def plotMedia(self, media): plt.title("Média Fitness", fontdict=None, loc='center', pad=None) plt.plot(media, color='b', linewidth=1.0) plt.show()
def run(parametros): prmt = { "npop": parametros[0], "nger": parametros[1], "tc": parametros[2], "tm": parametros[3], } melhores_solucoes = [] for _ in range(0, 5): populacao = Populacao(refeicoes, produtos_ids, dieta_kcal, prmt["npop"], prmt["tc"], prmt["tm"]) for _ in range(0, prmt["nger"]): populacao.avalia_pop(nutrientes_prod_dict, restricoes, penalidade=100) melhor_indiv = populacao.get_melhor_indiv() pais = populacao.torneio() indiv_interm = populacao.cruzamento(pais, refeicoes, produtos_ids) populacao.substituir_pop(indiv_interm) populacao.exec_elitismo(melhor_indiv) if melhor_indiv.kcal >= 1200: melhores_solucoes.append(melhor_indiv) return melhores_solucoes, prmt
# Selecao de pais # 1 == Aleatoria # 2 == Elitista # Selecao Sobreviventes # 1 == (mi, lambda) # 2 == (mi + lambda) # with open('a', 'wb') as arquivo: # pickle.dump({'populacao': [1, 2, 3]}, arquivo) # with open('a', 'rb') as arquivo: # a = pickle.load(arquivo) # print(a) combinacoes = [[1, 1, 1, 1], [2, 2, 2, 1], [3, 1, 1, 2], [2, 3, 2, 1], [2, 4, 2, 1], [2, 4, 2, 2], [1, 5, 1, 2], [3, 5, 2, 1]] for combinacao in combinacoes: ti = timer() p = Populacao() p.gerar_solucao(combinacao[0], combinacao[1], combinacao[2], combinacao[3]) tempo = timer() - ti with open(''.join(str(c) for c in combinacao), 'wb') as arquivo: pickle.dump( { 'populacao': p.populacao, 'execucoes': p.geracoes, 'tempo': tempo }, arquivo)
def executar(self): ambiente = Ambiente(self.__tamanho) amb = ambiente.gerarAmbiente() pop = Populacao(100, 0) vet_ag = pop.gerar_populacao() # for agente in vet_ag: # indice = vet_ag.index(agente) # id = '0_00_' + str(indice) # agente.set_id(id) memoria = mem() memoria.ordenar_memoria(vet_ag) vet_mem = memoria.get_memoria() for geracao in range(self.__ger): vet_ag = self.reproduzir(vet_ag.copy(), geracao) for ag in vet_ag: if ag.get_movimento() == []: ag.set_pontucao(-10) fitness = fit(ag.get_pontuacao(), 0) ag.set_fitness(fitness.calcular_fitness()) ag.set_tamanho(random.randint(10, 64)) ag.set_movimento(ag.gerar_movimento()) for agente in vet_ag: pos = [0, 0] pos_ant = [0, 0] rodada = 0 agente.viver() agente.reset_nice_moves() agente.reset_pontuacao() fitness, pontuacao = agente.pecado_inicial(agente) agente.set_fitness(fitness) agente.set_pontucao(pontuacao) acao_ant = '' for acao in agente.get_movimento(): movimento_bom = True if agente.get_vida(): amb[pos_ant[0]][pos_ant[1]].isAgente(False) agente.add_caminho_percorrido(list(pos)) if acao == 'n': pos[0] -= 1 elif acao == 's': pos[0] += 1 elif acao == 'l': pos[1] += 1 elif acao == 'o': pos[1] -= 1 if 0 > pos[0] or 3 < pos[0] or 0 > pos[1] or 3 < pos[1]: agente.set_pontucao(-300) agente.morrer() movimento_bom = False else: amb[pos[0]][pos[1]].isAgente(True) if acao_ant == 'fn' and acao == 'n': agente.set_pontucao(5) elif acao_ant == 'fn' and acao != 'n': agente.set_pontucao(-20) movimento_bom = False elif acao_ant == 'fs' and acao == 's': agente.set_pontucao(5) elif acao_ant == 'fs' and acao != 's': agente.set_pontucao(-20) movimento_bom = False elif acao_ant == 'fl' and acao == 'l': agente.set_pontucao(5) elif acao_ant == 'fl' and acao != 'l': agente.set_pontucao(-20) movimento_bom = False elif acao_ant == 'fo' and acao == 'o': agente.set_pontucao(5) elif acao_ant == 'fo' and acao != 'o': agente.set_pontucao(-20) movimento_bom = False if movimento_bom: agente.set_nice_moves(rodada) agente.set_pontucao(5) else: agente.set_pontucao(-10) acao_ant = acao pos_ant = pos.copy() rodada += 1 fitness = fit(agente.get_pontuacao(), len(agente.get_nice_moves())) # FITNESS AQUI!!! agente.set_fitness(fitness.calcular_fitness()) memoria_temp = mem() memoria_temp.ordenar_memoria(vet_ag.copy()) vet_memoria_temp = memoria_temp.get_memoria() for contador in range(len(vet_memoria_temp)): ja_existe = False for contador_b in range(len(vet_mem)): if vet_memoria_temp[contador].get_id( ) == vet_mem[contador_b].get_id(): ja_existe = True if not ja_existe: if vet_memoria_temp[contador].get_fitness( ) > vet_mem[-1].get_fitness(): vet_mem[-1] = vet_memoria_temp[contador] memoria.ordenar_memoria(vet_mem.copy()) vet_mem = memoria.get_memoria() vet_ag = list(vet_mem) num_eliminados = int(len(vet_ag) * 0.6) for contador in range(num_eliminados): vet_ag.pop(-1) nova_pop = Populacao(num_eliminados, geracao) vet_nova_pop = nova_pop.gerar_populacao() vet_ag += list(vet_nova_pop) escolhida = vet_mem[0] print( f"Id: {escolhida.get_id()} - Fitness: {escolhida.get_fitness()} - Pontuação: {escolhida.get_pontuacao()} - Movimento: {escolhida.get_movimento()}" )
class AlgGenetico: ''' Algoritmo Genético Esta classe visa facilitar a utilização do Algoritmo Genético formado pelas classes Cromossomo e População ''' __tipoGenes = None __qntIndividuos = None __funcaoAvaliacao = None __criterioSatisfacao = None __considMaiorAvaliacao = None __maxGeracoes = None __Populacao = None __retCromo = None __verboso = None def __init__(self, tipoGenes, qntIndividuos, funcaoAvaliacao, \ criterioSatisfacao=0.0, considMaiorAvaliacao=True, \ maxGeracoes=10, verboso=False, retCromo=True, distribuido=False): ''' Construtor da classe @param tipoGenes: Matriz com os tipos de Genes que podem ser utilizados nos indivíduos @param qntIndividuos: Quantidade de indivíduos que uma população pode ter @param funcaoAvaliacao: Função externa que deverá receber o Cromossomo como parâmetro e retornar seu valor de satisfação @param criterioSatisfacao: valor de satisfação esperado pelo cromossomo (critério de satisfação) @param considMaiorAvaliacao: Informa que os indivíduos com os valores menor devem ser descartados. Para descartar os indivíduos com o maior valor, utilize considMaiorAvaliacao=False @param maxGeracoes: Informa qual o máximo de gerações, ou seja, o máximo de cruzamentos realizados. O padrão é maxGeracoes=0, onde o critério de término será o "criterioSatisfacao" @param verboso: Imprime mensagens na tela no decorrer do processo @param retCromo: Indica se a função de avaliação vai trabalhar com o Cromossomo(True) ou com seu vetor(False) ''' try: if type(tipoGenes[0]) != type(list()): raise Exception("ERRO: tipoGenes deve ser uma matriz!") except: raise Exception("ERRO: tipoGenes deve ser uma matriz!") self.__tipoGenes = tipoGenes self.__qntIndividuos = qntIndividuos self.__funcaoAvaliacao = funcaoAvaliacao self.__criterioSatisfacao = criterioSatisfacao self.__considMaiorAvaliacao = considMaiorAvaliacao self.__maxGeracoes = maxGeracoes self.__retCromo = retCromo self.__verboso = verboso self.__Populacao = None self.__distribuido = distribuido def ordenaPorAvaliacao(self, cromo): ''' Método que devolve a avaliação do cromossomo @param: Cromossomo @return: Avaliação do cromossomo ''' return cromo.getAvaliacao() def verCriterioTerminacao(self): ''' Verifica se algum dos cromossomos atingiu o critério de término @return: True -> a população alcançou a critério de término False -> a população não alcançou a critério de término ''' retorno = [] for cromo in self.__Populacao.getIndividuos(): if self.__considMaiorAvaliacao: if cromo.getAvaliacao() >= self.__criterioSatisfacao: retorno.append(cromo) else: if cromo.getAvaliacao() <= self.__criterioSatisfacao: retorno.append(cromo) retorno.sort(key=self.ordenaPorAvaliacao, reverse=self.__considMaiorAvaliacao) if len(retorno) == 0: return False, retorno else: return True, retorno def evoluir(self): ''' Método responsável por controlar toda a execução do algoritmo genético, incluindo os cruzamentos e a mutação @return: a última população de cromossomos ''' retorno = [] self.__Populacao = Populacao(self.__tipoGenes, distribuido=self.__distribuido, maiorValor=self.__considMaiorAvaliacao) self.__Populacao.gerarPopulacao(self.__qntIndividuos) self.__Populacao.avaliarPopulacao(self.__funcaoAvaliacao) if self.__criterioSatisfacao != 0.0: resp, cromos = self.verCriterioTerminacao() Ger = 1 if self.__maxGeracoes == 0: while not resp: self.__Populacao.geraNovaPopulacao(self.__funcaoAvaliacao, self.__considMaiorAvaliacao) resp, cromos = self.verCriterioTerminacao() if self.__verboso: print "Indivíduos que alcançaram o critério de Satisfação:" for i in cromos: retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() elif self.__criterioSatisfacao != 0.0: while not resp and Ger <= self.__maxGeracoes: if self.__verboso: print "Geração:", Ger self.__Populacao.geraNovaPopulacao(self.__funcaoAvaliacao, self.__considMaiorAvaliacao) resp, cromos = self.verCriterioTerminacao() Ger += 1 if resp: if self.__verboso: print "Indivíduos que alcançaram o critério de Satisfação:" for i in cromos: retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() else: if self.__verboso: print "Indivíduos não alcançaram o critério de Satisfação!" if self.__verboso: print "A última população foi:" for i in self.__Populacao.getIndividuos(): retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() else: for Ger in range(self.__maxGeracoes): if self.__verboso: print "Geração:", Ger self.__Populacao.geraNovaPopulacao(self.__funcaoAvaliacao, self.__considMaiorAvaliacao, self.__retCromo) if self.__verboso: print "A última população foi:" for i in self.__Populacao.getIndividuos(): retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() return retorno
class AlgGenetico: ''' Algoritmo Genético Esta classe visa facilitar a utilização do Algoritmo Genético formado pelas classes Cromossomo e População ''' __tipoGenes = None __qntIndividuos = None __funcaoAvaliacao = None __criterioSatisfacao = None __considMaiorAvaliacao = None __maxGeracoes = None __Populacao = None __retCromo = None __verboso = None def __init__(self, tipoGenes, qntIndividuos, funcaoAvaliacao, \ criterioSatisfacao=0.0, considMaiorAvaliacao=True, \ maxGeracoes=10, verboso=False, retCromo=True, distribuido=False): ''' Construtor da classe @param tipoGenes: Matriz com os tipos de Genes que podem ser utilizados nos indivíduos @param qntIndividuos: Quantidade de indivíduos que uma população pode ter @param funcaoAvaliacao: Função externa que deverá receber o Cromossomo como parâmetro e retornar seu valor de satisfação @param criterioSatisfacao: valor de satisfação esperado pelo cromossomo (critério de satisfação) @param considMaiorAvaliacao: Informa que os indivíduos com os valores menor devem ser descartados. Para descartar os indivíduos com o maior valor, utilize considMaiorAvaliacao=False @param maxGeracoes: Informa qual o máximo de gerações, ou seja, o máximo de cruzamentos realizados. O padrão é maxGeracoes=0, onde o critério de término será o "criterioSatisfacao" @param verboso: Imprime mensagens na tela no decorrer do processo @param retCromo: Indica se a função de avaliação vai trabalhar com o Cromossomo(True) ou com seu vetor(False) ''' try: if type(tipoGenes[0]) != type( list() ): raise Exception("ERRO: tipoGenes deve ser uma matriz!") except: raise Exception("ERRO: tipoGenes deve ser uma matriz!") self.__tipoGenes = tipoGenes self.__qntIndividuos = qntIndividuos self.__funcaoAvaliacao = funcaoAvaliacao self.__criterioSatisfacao = criterioSatisfacao self.__considMaiorAvaliacao = considMaiorAvaliacao self.__maxGeracoes = maxGeracoes self.__retCromo = retCromo self.__verboso = verboso self.__Populacao = None self.__distribuido = distribuido def ordenaPorAvaliacao(self, cromo): ''' Método que devolve a avaliação do cromossomo @param: Cromossomo @return: Avaliação do cromossomo ''' return cromo.getAvaliacao() def verCriterioTerminacao(self): ''' Verifica se algum dos cromossomos atingiu o critério de término @return: True -> a população alcançou a critério de término False -> a população não alcançou a critério de término ''' retorno = [] for cromo in self.__Populacao.getIndividuos(): if self.__considMaiorAvaliacao: if cromo.getAvaliacao() >= self.__criterioSatisfacao: retorno.append( cromo ) else: if cromo.getAvaliacao() <= self.__criterioSatisfacao: retorno.append( cromo ) retorno.sort(key=self.ordenaPorAvaliacao, reverse=self.__considMaiorAvaliacao) if len( retorno ) == 0: return False, retorno else: return True, retorno def evoluir(self): ''' Método responsável por controlar toda a execução do algoritmo genético, incluindo os cruzamentos e a mutação @return: a última população de cromossomos ''' retorno = [] self.__Populacao = Populacao( self.__tipoGenes, distribuido=self.__distribuido, maiorValor=self.__considMaiorAvaliacao ) self.__Populacao.gerarPopulacao( self.__qntIndividuos ) self.__Populacao.avaliarPopulacao( self.__funcaoAvaliacao ) if self.__criterioSatisfacao != 0.0: resp, cromos = self.verCriterioTerminacao() Ger = 1 if self.__maxGeracoes == 0: while not resp: self.__Populacao.geraNovaPopulacao( self.__funcaoAvaliacao, self.__considMaiorAvaliacao) resp, cromos = self.verCriterioTerminacao() if self.__verboso: print "Indivíduos que alcançaram o critério de Satisfação:" for i in cromos: retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() elif self.__criterioSatisfacao != 0.0: while not resp and Ger <= self.__maxGeracoes: if self.__verboso: print "Geração:", Ger self.__Populacao.geraNovaPopulacao( self.__funcaoAvaliacao, self.__considMaiorAvaliacao) resp, cromos = self.verCriterioTerminacao() Ger+=1 if resp: if self.__verboso: print "Indivíduos que alcançaram o critério de Satisfação:" for i in cromos: retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() else: if self.__verboso: print "Indivíduos não alcançaram o critério de Satisfação!" if self.__verboso: print "A última população foi:" for i in self.__Populacao.getIndividuos(): retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() else: for Ger in range(self.__maxGeracoes): if self.__verboso: print "Geração:", Ger self.__Populacao.geraNovaPopulacao( self.__funcaoAvaliacao, self.__considMaiorAvaliacao, self.__retCromo) if self.__verboso: print "A última população foi:" for i in self.__Populacao.getIndividuos(): retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() return retorno
def evoluir(self): ''' Método responsável por controlar toda a execução do algoritmo genético, incluindo os cruzamentos e a mutação @return: a última população de cromossomos ''' retorno = [] self.__Populacao = Populacao( self.__tipoGenes, distribuido=self.__distribuido, maiorValor=self.__considMaiorAvaliacao ) self.__Populacao.gerarPopulacao( self.__qntIndividuos ) self.__Populacao.avaliarPopulacao( self.__funcaoAvaliacao ) if self.__criterioSatisfacao != 0.0: resp, cromos = self.verCriterioTerminacao() Ger = 1 if self.__maxGeracoes == 0: while not resp: self.__Populacao.geraNovaPopulacao( self.__funcaoAvaliacao, self.__considMaiorAvaliacao) resp, cromos = self.verCriterioTerminacao() if self.__verboso: print "Indivíduos que alcançaram o critério de Satisfação:" for i in cromos: retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() elif self.__criterioSatisfacao != 0.0: while not resp and Ger <= self.__maxGeracoes: if self.__verboso: print "Geração:", Ger self.__Populacao.geraNovaPopulacao( self.__funcaoAvaliacao, self.__considMaiorAvaliacao) resp, cromos = self.verCriterioTerminacao() Ger+=1 if resp: if self.__verboso: print "Indivíduos que alcançaram o critério de Satisfação:" for i in cromos: retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() else: if self.__verboso: print "Indivíduos não alcançaram o critério de Satisfação!" if self.__verboso: print "A última população foi:" for i in self.__Populacao.getIndividuos(): retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() else: for Ger in range(self.__maxGeracoes): if self.__verboso: print "Geração:", Ger self.__Populacao.geraNovaPopulacao( self.__funcaoAvaliacao, self.__considMaiorAvaliacao, self.__retCromo) if self.__verboso: print "A última população foi:" for i in self.__Populacao.getIndividuos(): retorno.append(i) if self.__verboso: print i.getCromossomo(), i.getAvaliacao() return retorno
import random import math from Populacao import Populacao TAMANHO_INDIVIDUO = 4 TAMANHO_POPULACAO = 2 populacao = Populacao(TAMANHO_POPULACAO, TAMANHO_INDIVIDUO) populacao.gerarPopulacao() populacao.calcularFitness() populacao.fazerMutacao()
def main(): # if('--help' in sys.argv): # print('\033[93m'+'Parâmetros: \n\ # --geracional True ou False. Padrão: False. \n\ # Indica se a seleção de sobreviventes utilizada será a geracional \n\ # --mutacao 1 ou 2. Padrão: 1. \n\ # Escolhe entre as duas opções de mutação \n\ # 1: Mutação de troca de posição entre 2 valores \n\ # 2: Mutação de troca de valores de uma região \n\ # --pop 0 à n (inteiro). Padrão: 100. \n\ # Define o tamanho "n" da população \n\ # --tabuleiro 0 à n (inteiro). Padrão: 8. \n\ # Define o tamanho do tabuleiro (e rainhas nele) \n\ # --roleta True ou False. Padrão: False. \n\ # Indica se o método de seleção dos pais vai ser roleta \n\ # --cruzamento 1 ou 2 ou 3. Padrão: 1. \n\ # Escolhe entre as três opções de recombinação \n\ # 1: Cut and crossfill crossover \n\ # 2: Cycle Crossover \n\ # 3: Partially Mapped Crossover \n\ # '+'\033[92m') # print(sys.argv) # exit() # else: # print('\033[93m'+'Se tiver dúvidas, execute: py main.py --help'+'\033[0m') geracional = False roleta = False mutacao = 1 cruz = 1 pop = 100 tab = 8 # Parser # for sargs in range(0, len(sys.argv)): # try: # if sys.argv[sargs] == '--mutacao': # mutacao = int(sys.argv[sargs+1]) # if sys.argv[sargs] == '--geracional': # geracional = eval(sys.argv[sargs+1]) # if sys.argv[sargs] == '--roleta': # roleta = eval(sys.argv[sargs+1]) # if sys.argv[sargs] == '--pop': # pop = int(sys.argv[sargs+1]) # if sys.argv[sargs] == '--tabuleiro': # tab = int(sys.argv[sargs+1]) # if sys.argv[sargs] == '--cruzamento': # cruz = int(sys.argv[sargs+1]) # except: # print('Erro de formatação do input!') # exit() # print(mutacao, geracional, roleta, pop, tab, cruz) with open(file=arqnome, mode='w', newline='') as csvfile: escritor = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) escritor.writerow(['Execução', 'Execuções Necessárias', 'Fitness Médio', 'Desvio Padrão do Fitness', 'Número de Indivíduos Convergentes']) for i in range(1, execs+1): p = Populacao(n=tab, popsize=pop) p.generateSolution(geracional=geracional, roleta=roleta, tiporecomb=cruz, tipomut=mutacao) ind_conv = [j.fitness for j in p.pop].count(1) ind_fit_med, ind_fit_dp = mean([j.fitness for j in p.pop]), std([j.fitness for j in p.pop]) print('Execuções Necessárias: {} \n\ Fitness Médio: {} \n\ Desvio Padrão: {} \n\ Número de Indivíduos Convergentes: {} \n' .format(p.ger-1, ind_fit_med, ind_fit_dp, ind_conv)) escrever(i, p.ger-1, ind_fit_med, ind_fit_dp, ind_conv) avaliacao() return
import random import math from Populacao import Populacao import graficoFitnessMedio as grafico TAMANHO_INDIVIDUO = 5 TAMANHO_POPULACAO = 100 #inicializacao da populacao populacao = Populacao(TAMANHO_POPULACAO, TAMANHO_INDIVIDUO) populacao.inicializar() #funcao principal for i in range(8): populacao.calcularFitnessMedio() populacao.selecao() populacao.reproducao(70) populacao.mutacao() grafico.plotar(populacao)
def executar(self): maximos = [] minimos = [] medias = [] mortes_poco = [] mortes_wumpus = [] sucessos = [] ambiente = Ambiente(self.__tamanho) amb = ambiente.gerarAmbiente() pop = Populacao(100, 0, self.__tamanho) vet_ag = pop.gerar_populacao() memoria = mem() memoria.ordenar_memoria(vet_ag) vet_mem = memoria.get_memoria() for geracao in range(self.__ger): vet_ag = self.reproduzir(vet_ag.copy(), geracao) num_mortes_poco = 0 num_mortes_wumpus = 0 num_sucesso = 0 for ag in vet_ag: if ag.get_movimento() == []: ag.set_pontucao(2) fitness = fit(ag.get_pontuacao(), 0, 0, 0, self.__tamanho) #<<< ag.set_fitness(fitness.calcular_fitness()) ag.set_tamanho(random.randint(10, 64)) ag.set_movimento(ag.gerar_movimento()) for agente in vet_ag: pos = [0, 0] # Define a posição inicial como [0, 0] pos_ant = [0, 0] # Define a posição anterior como [0, 0] rodada = 0 # Começa pela rodada 0 acao_ant = '' # Define a ação anterior como nula caminho_ate_ouro = 0 # Define o caminho até o ouro como nulo wumpus_vivo = True agente.viver() # Revive o agente agente.recarregar() # Recarrega a 'aljava' agente.reset_nice_moves() # Define os movimentos bons como 0 agente.reset_caminho_percorrido() # Define o caminho percorrido como nulo agente.reset_pontuacao() # Define a pontuação como 0 agente.reset_ouro() # Tira o ouro do agente fitness, pontuacao = agente.pecado_inicial(agente) # Aplica as pontuações iniciais agente.set_fitness(fitness) # Define o fitness inicial agente.set_pontucao(pontuacao) # Define a pontuação inicial agente.add_caminho_percorrido(list(pos)) # Adiciona [0, 0] ao caminho percorrido mov_sem_ouro = 0 for acao in agente.get_movimento(): # Se o agente estiver com o ouro e tiver andado mais casas do que precisou para chegar até o ouro if agente.get_ouro() and len(agente.get_caminho_percorrido()) > caminho_ate_ouro*2: movimento_bom = False # Qualquer movimento será considerado ruim else: # Caso contrário movimento_bom = True # O movimento a seguir tem a possibilidade de ser bom if agente.get_vida(): # Executa enquanto o agente estiver vivo amb[pos_ant[0]][pos_ant[1]].isAgente(False) # Remove o agente da sua posição anterior if acao == 'n': # Anda pro norte pos[0] -= 1 elif acao == 's': # Anda pro sul pos[0] += 1 elif acao == 'l': # Anda pro leste pos[1] += 1 elif acao == 'o': # Anda pro oeste pos[1] -= 1 # Se o agente andar para fora da matriz if 0 > pos[0] or 3 < pos[0] or 0 > pos[1] or 3 < pos[1]: agente.set_pontucao(0) # Recebe pontução nula agente.morrer() # Morre movimento_bom = False # O movimento é ruim else: # Caso contrário agente.add_caminho_percorrido(list(pos)) # A posição atual é adicionada à lista de casas amb[pos[0]][pos[1]].isAgente(True) # A casa recebe o agente # Se o agente quiser disparar e possuir flecha if (acao == 'fn' or acao == 'fs' or acao == 'fl' or acao == 'fo') and agente.get_flecha(): agente.disparar() # Pode disparar if acao == 'fn': if ambiente.getWumpus() == [pos[0] - 1, pos[1]]: wumpus_vivo = False agente.set_pontucao(256) else: movimento_bom = False agente.set_pontucao(2) elif acao == 'fs': if ambiente.getWumpus() == [pos[0] + 1, pos[1]]: wumpus_vivo = False agente.set_pontucao(256) else: movimento_bom = False agente.set_pontucao(2) elif acao == 'fl': if ambiente.getWumpus() == [pos[0], pos[1] + 1]: wumpus_vivo = False agente.set_pontucao(256) else: movimento_bom = False agente.set_pontucao(2) elif acao == 'fo': if ambiente.getWumpus() == [pos[0], pos[1] - 1]: wumpus_vivo = False agente.set_pontucao(256) else: movimento_bom = False agente.set_pontucao(2) elif(acao == 'fn' or acao == 'fs' or acao == 'fl' or acao == 'fo') and not agente.get_flecha(): movimento_bom = False # Pode disparar, porém o movimento é ruim if pos == ambiente.getWumpus() and wumpus_vivo: num_mortes_wumpus += 1 agente.morrer() agente.set_pontucao(1) movimento_bom = False for casa in ambiente.getPoco(): if pos == casa: # Se a posição atual for igual à de um poço num_mortes_poco += 1 agente.morrer() # O agente morre agente.set_pontucao(2) # Recebe 2pts movimento_bom = False # O movimento é considerado ruim if acao == 'p': # Se a ação atual for "pegar" # Se houver ouro na casa e a quantidade de pegar for == 1 if pos == ambiente.getOuro() and agente.get_movimento().count('p') == 1: agente.pegar_ouro() # O agente pega o ouro # É definido o tamanho do caminho até o ouro caminho_ate_ouro = len(agente.get_caminho_percorrido()) else: # Caso contrário agente.set_pontucao(1) # O agente recebe 1pt movimento_bom = False # O movimento é considerado ruim if not agente.get_ouro(): mov_sem_ouro += 1 if movimento_bom: agente.set_nice_moves(rodada) agente.set_pontucao(4) else: agente.set_bad_moves(rodada) agente.set_pontucao(2) acao_ant = acao pos_ant = pos.copy() rodada += 1 if agente.get_ouro() and agente.get_caminho_percorrido()[-1] == [0, 0]: num_sucesso += 1 if len(agente.get_caminho_percorrido()) < self.__tamanho*5: agente.set_pontucao(2048) else: agente.set_pontucao(1024) elif agente.get_ouro() and agente.get_caminho_percorrido()[-1] != [0, 0]: agente.set_pontucao(1) if agente.get_flecha(): agente.set_pontucao(129) fitness = fit(agente.get_pontuacao(), len(agente.get_nice_moves()), len(agente.get_bad_moves()), mov_sem_ouro, self.__tamanho) #<<< agente.set_fitness(fitness.calcular_fitness()) memoria_temp = mem() memoria_temp.ordenar_memoria(vet_ag.copy()) vet_memoria_temp = memoria_temp.get_memoria() fitness_maximo = vet_memoria_temp[0].get_fitness() maximos.append(fitness_maximo) fitness_minimo = vet_memoria_temp[-1].get_fitness() minimos.append(fitness_minimo) total_fitness = 0 for celula in vet_memoria_temp: total_fitness += celula.get_fitness() media_fitness = total_fitness/len(vet_memoria_temp) medias.append(media_fitness) sucessos.append(num_sucesso) mortes_poco.append(num_mortes_poco) mortes_wumpus.append(num_mortes_wumpus) for contador in range(len(vet_memoria_temp)): ja_existe = False for contador_b in range(len(vet_mem)): if vet_memoria_temp[contador].get_id() == vet_mem[contador_b].get_id(): ja_existe = True if not ja_existe: if vet_memoria_temp[contador].get_fitness() > vet_mem[0].get_fitness(): vet_mem[-1] = vet_mem[0] vet_mem[0] = vet_memoria_temp[contador] memoria.ordenar_memoria(vet_mem.copy()) vet_mem = memoria.get_memoria() elif vet_memoria_temp[contador].get_fitness() > vet_mem[-1].get_fitness(): vet_mem[-1] = vet_memoria_temp[contador] memoria.ordenar_memoria(vet_mem.copy()) vet_mem = memoria.get_memoria() vet_ag = list(vet_mem) num_eliminados = int(len(vet_ag)*0.6) for contador in range(num_eliminados): vet_ag.pop(-1) nova_pop = Populacao(num_eliminados, geracao, self.__tamanho) vet_nova_pop = nova_pop.gerar_populacao() vet_ag += list(vet_nova_pop) vet_mem[0].imprimir_agente() # print(f"Poços: {ambiente.getPoco()}\nOuro: {ambiente.getOuro()}\nWumpus: {ambiente.getWumpus()}") # vet_mem[0].imprimir_agente() dados = [maximos, minimos, medias, sucessos, mortes_wumpus, mortes_poco] return dados, vet_mem[0]
class AlgoritmoGenetico(): def __init__(self, taxaCrossover, taxaMutacao, geracoes, numPopulacao, limiteEspacos, gastoMaximo, qtdElite): self.taxaCrossover = taxaCrossover self.taxaMutacao = taxaMutacao self.geracoes = geracoes self.numPopulacao = numPopulacao self.qtdElite = qtdElite self.melhorSolucao = None self.populacao = Populacao(numPopulacao, limiteEspacos, gastoMaximo) self.melhorSolucao = self.populacao.listaDeIndividuos[0] def executarAG(self): print('GERAÇÃO 1') self.populacao.printPopulacao() print('\n') for i in range(self.geracoes - 1): print('GERAÇÃO {}'.format(i + 2)) self.populacao.setListaDeIndividuos(self.elitista()) self.mutacao() self.populacao.avaliar() self.populacao.ordernarPopulacao() self.populacao.printPopulacao() self.melhorSolucao = self.populacao.melhorIndividuo( self.melhorSolucao) print('\n\n') print('MELHOR SOLUÇÃO ENCONTRADA:') self.printMelhorSolucao(self.melhorSolucao) print('\n\n') print('MELHOR SOLUÇÃO ENCONTRADA NA GERAÇÃO ATUAL:') self.printMelhorSolucao(self.populacao.listaDeIndividuos[0]) ''' Realiza a seleção do individuo mais apto por torneio, considerando N = 2 ''' def selecionarTorneio(self): individuo_1 = self.populacao.listaDeIndividuos[randint( 0, self.numPopulacao - 1)] individuo_2 = self.populacao.listaDeIndividuos[randint( 0, self.numPopulacao - 1)] # retorna individuo com a maior avaliação, ou seja, o vencedor do torneio if individuo_1.fitness > individuo_2.fitness: return individuo_1 else: return individuo_2 ''' Clona uma quantidade pré-definida dos melhores indivíduos para a próxima geração. ''' def elitista(self): self.populacao.setListaDeIndividuos( sorted(self.populacao.listaDeIndividuos, key=Individuo.getFitness, reverse=True)) novaGeracao = [] for i in range(self.qtdElite): novaGeracao.append(self.populacao.listaDeIndividuos.pop()) self.numPopulacao = len(self.populacao.listaDeIndividuos) return self.crossover(novaGeracao) ''' Cruzamento entre dois pais para criação de dois filhos. É definido um ponto de corte aleatório em cada cromossomo e os segmentos de cromossomo criados a partir dos pontos de corte são trocados, criando dois novos indivíduos. ''' def crossover(self, novaGeracao): for i in range(int(self.numPopulacao / 2)): individuo_1 = self.selecionarTorneio() individuo_2 = self.selecionarTorneio() if (random() < self.taxaCrossover): pontoCorte = round(random() + len(individuo_1.cromossomo)) filho_1 = individuo_2.cromossomo[ 0:pontoCorte] + individuo_1.cromossomo[pontoCorte::] filho_2 = individuo_1.cromossomo[ 0:pontoCorte] + individuo_2.cromossomo[pontoCorte::] descricaoJogo = [] descricaoJogo = self.populacao.copiarAtributosJogos() filhos = [ Individuo(descricaoJogo[0], descricaoJogo[1], descricaoJogo[2], len(self.populacao.listaJogos)), Individuo(descricaoJogo[0], descricaoJogo[1], descricaoJogo[2], len(self.populacao.listaJogos)) ] filhos[0].setCromossomo(filho_1) filhos[0].setGeracao(individuo_1.geracao) filhos[1].setCromossomo(filho_2) filhos[1].setGeracao(individuo_1.geracao) novaGeracao.append(filhos[0]) novaGeracao.append(filhos[1]) else: novaGeracao.append(individuo_1) novaGeracao.append(individuo_2) return novaGeracao def mutacao(self): for individuo in self.populacao.listaDeIndividuos: individuo.mutarBit(self.taxaMutacao, len(self.populacao.listaJogos)) ''' Print da melhor solução (indivíduo) recebido. ''' def printMelhorSolucao(self, melhorSolucao): print("GERAÇÃO: " + str(melhorSolucao.geracao)) melhorSolucao.printCromossomo() print() qtdGenes = len(melhorSolucao.cromossomo) cromossomo = melhorSolucao.cromossomo for i in range(qtdGenes): if cromossomo[i] == 1: print('Jogo: {} Espaço: {} Preço: {} Valor: {}'.format( self.populacao.listaJogos[i].nome, self.populacao.listaJogos[i].espaco, self.populacao.listaJogos[i].preco, self.populacao.listaJogos[i].valor))
from Populacao import Populacao from Rainhas import Rainhas if __name__ == "__main__": populacao = Populacao(Rainhas, 20) populacao.evoluir(30)
def executar(self): resultados = pd.DataFrame({ 'melhores': [], 'piores': [] }) # Cria o DF para armazenar os resultados mapa = Mapa( self.__mapa) # Instancia e lê as coordenadas do mapa escolhido cidades = mapa.ler_coordenadas() pop = Populacao(self.__num_cel, self.__validade, cidades, 0) # Instancia uma nova população populacao = pop.gerar_populacao() # Gera o DF da população populacao.sort_values( by='fitness', inplace=True) # Ordena a população de acordo com o fitness populacao.index = range( populacao.shape[0]) # Ajusta o índice da população mem = Memoria(populacao[:self.__tamanho_mem].copy() ) # Armazena na memória uma parcela da população mem.ordenar_memoria() # Ordena a memória for geracao in range(self.__num_ger): # Para cada geração: # Clona a população de acordo com a quantidade estipulada de clones populacao = clonar(populacao, self.__num_clones, geracao, self.__validade, cidades) populacao = pd.DataFrame(populacao) # Ordena os valores da população de acordo com o 'fitness' populacao.sort_values(by='fitness', inplace=True) populacao.index = range(populacao.shape[0]) # Cria um data set temporário para a memória memoria = pd.DataFrame(mem.get_memoria()) # Verifica uma a uma as células presentes na memória for index, celula in populacao.iterrows(): # Armazena o pior valor de fitness pior_fit = memoria.fitness.max() # Verifica quais células já estão presentes na memória de acordo com o fitness talvez_exista = memoria.fitness == celula.fitness existe = False for possibilidade in talvez_exista: if possibilidade: existe = True # Armazena somente as células que não estão presentes na memória e possuem um 'fitness' melhor do que o # pior já armazenado if (celula.fitness < pior_fit) and (not existe): memoria.drop([memoria.shape[0] - 1], inplace=True) # Remove a última célula memoria = memoria.append( celula, ignore_index=True) # Adiciona a célula nova memoria.sort_values( by='fitness', inplace=True ) # Ordena a população de acordo com o fitness memoria.index = range( memoria.shape[0]) # Ajusta o índice da população # Armazena o melhor fitness da memória e o pior fitness da população resultados = resultados.append( { 'melhores': memoria.fitness.min().copy(), 'piores': populacao.fitness.max().copy() }, ignore_index=True) # Diminui a validade das células memoria.validade -= 1 # Verifica uma a uma as células presentes na memória for index, row in memoria.iterrows(): if row.validade < 0: # Modifica o fitness se a validade for menor que zero memoria.loc[index, 'fitness'] += row.fitness * 0.5 populacao = memoria.copy() populacao = clonar(populacao, int(self.__num_cel / self.__tamanho_mem - 1), geracao, self.__validade, cidades) populacao.sort_values(by='fitness', inplace=True) populacao.index = range(populacao.shape[0]) mem.set_memoria(memoria.copy()) mem.ordenar_memoria() print( f'\n### {geracao} - {self.__execucao} ###\n{populacao.loc[0, "fitness"]}' ) return resultados