def __init__(self,n): self.tabu = self.tabu * n self.allowed = self.allowed * n # Colocando a formiga em uma posição (item) aleatória para começar pos = d519.randrange(0,n) self.tabu[pos] = 1 self.allowed[pos] = 0
def __init__(self, n, novo=False): self.alelos = self.alelos * n if novo: return # Gerando posições de alelos aleatórias if tipoProblema == 0: aleatorio = int(n * 0.1) else: aleatorio = int(n * 0.1) for i in range(0, aleatorio): # até 50% da solução inicial self.alelos[d519.randrange(0, n)] = True """ for i in range(0,n): if d519.randrange(0,100) > 89: self.alelos[i] = True """ """ # Gerando posições de alelos gulosos for i in range(0,n): if V[i]/float(M[i]) > 3: self.alelos[i] = True """ self.calculaPeso() self.calculaValor() # Verifica se respeita o knapsack if tipoProblema == 0: while self.peso > W: # Retira um item aleatorio tmp = d519.randrange(0, n) self.alelos[tmp] = False # Recalculo self.valor = self.valor - V[tmp] self.peso = self.peso - M[tmp] else: while self.calculaICAlim() < ICLimite: # Adiciona um item aleatorio tmp = d519.randrange(0, n) self.alelos[tmp] = True # Recalculo self.valor = self.valor + V[tmp] self.peso = self.peso + M[tmp]
def __init__(self, n, primeiraGeracao): self.tabu = self.tabu * n # Colocando a formiga em uma posição (item) aleatória para começar if primeiraGeracao: if tipoProblema == 0: pos = d519.randrange(0, n) self.tabu[pos] = 1 self.valor = self.valor + V[pos] self.peso = self.peso + M[pos] else: for i in range(0, len(self.tabu)): self.tabu[i] = 1 self.valor = self.valor + V[i] self.peso = self.peso + M[i] pos = d519.randrange(0, n) self.tabu[pos] = 0 self.valor = self.valor - V[pos] self.peso = self.peso - M[pos]
def roleta(aux, P): # Gera um número aleatório [0,1] roleta = d519.randrange(0,100)/float(100) i = 0 total = 0 while True: total = total+P[aux[i]] if total < roleta: # Passa para proximo i = i+1 else: return aux[i] # selecionado
def buscaLocal(solucaoCorrente): global avaliacoes # Rodo iterMax vezes k = 0 # Armazeno o valor e peso atuais para não recalcular a todo momento valorCorrente = calculaValor(solucaoCorrente) pesoCorrente = calculaPeso(solucaoCorrente) valorBL = valorCorrente pesoBL = pesoCorrente # Encontrando um vizinho k qualquer s0 = d519.copy.copy(solucaoCorrente) while k < iterMaxBL: k = k+1 #j = 0 #while j < iterMaxBL_P: # Altera UMA posição # Mudo uma posicao pos = d519.randrange(0,len(s0)) if s0[pos]: s0[pos] = False valorBL = valorBL - ics[pos] pesoBL = pesoBL - custos[pos] else: s0[pos] = True valorBL = valorBL + ics[pos] pesoBL = pesoBL + custos[pos] avaliacoes = avaliacoes + 1 # RESTRIÇÃO: Verificando se a soma das trocas são válidas if tipoProblema == 0: if pesoBL > meuCusto: return solucaoCorrente else: if calculaICAlim(s0) < ICLimite: return solucaoCorrente if tipoProblema == 0: # Se sim, entao verifico qual tem IC melhor # Usar >= aqui pode implicar em loop infinito quando muito próximo do ótimo if valorBL > valorCorrente: solucaoCorrente = d519.copy.copy(s0) # nova solução corrente #valorCorrente = valorBL #s0 = d519.copy.copy(solucaoCorrente) else: if pesoBL < pesoCorrente: solucaoCorrente = d519.copy.copy(s0) return solucaoCorrente #[0]*len(solucaoCorrente)
########### PARAMETROS ########### # Numero de gerações g = 99 # Numero de formigas m = 100 # Generally, it is defined that the number of ants (m) is equal to that of articles (n) ants = [] M=[8, 19, 38, 66, 15, 62, 19, 95, 74, 55, 7, 41, 65, 65, 61, 29, 82, 45, 27, 7, 97, 79, 91, 14, 93, 41, 61, 55, 80, 74, 27, 66, 72, 49, 33, 47, 55, 61, 40, 16, 60, 29, 68, 9, 21, 88, 74, 10, 32, 96, 45, 98, 39, 42, 9, 40, 48, 2, 56, 36, 7, 50, 52, 59, 98, 64, 52, 87, 54, 23, 64, 84, 18, 64, 92, 56, 40, 31, 47, 36, 80, 61, 27, 61, 35, 55, 34, 39, 46, 82, 42, 81, 35, 10, 54, 24, 84, 2, 11, 49] V=[27, 48, 99, 54, 42, 43, 38, 96, 49, 81, 85, 63, 89, 46, 73, 3, 9, 3, 89, 89, 20, 32, 1, 92, 88, 71, 76, 47, 7, 32, 22, 66, 32, 26, 1, 94, 6, 58, 67, 37, 58, 94, 79, 1, 17, 1, 65, 61, 92, 57, 67, 60, 78, 23, 93, 58, 52, 82, 50, 24, 49, 42, 54, 21, 83, 70, 1, 53, 7, 5, 3, 26, 60, 98, 21, 71, 19, 36, 74, 50, 16, 97, 15, 24, 8, 78, 9, 67, 22, 41, 17, 11, 87, 25, 87, 89, 69, 4, 7, 27] # Total itens n = len(M) # Constante inicial de ferormonio C = 1 # Constante Q randômica para cálculo de G(Weight_k) 10 < Q < 100 Q = d519.randrange(11,100) # Constantes alpha e beta para função de probabilidade 0 < alpha < 5 e 0 <= beta <= 5 alpha = 1 beta = 1 # Permanencia do ferormonio rho = 0.7 # Lista de ferormonio em cada item ferormonio = [C] * n ferormonioDelta = [0] * n class Ant: """ Nesta modelagem, cada formiga é um objeto com suas propriedades de solução. Os itens estão representados pelos vetores M e V e os ferormônios atualizados também de acordo com eles """ tabu = [0]
def mono_ils(params): debug = params[0] melhoresGeracao = [] # a resposta do algoritmo, para cada geração uma única resposta será enviada ########### PARAMETROS ################# # Número máximo de iterações no loop princpal do ILS. iterMaxILS = params[1]#600 # Número máximo de iterações na busca local. 10% do tamanho da populacao # Isto fará com que chegue uma hora em que a restrição monetária não suporte nenhuma outra solução iterMaxBL = params[2]#20 pPert = params[3] #2 # @deprecated iterMaxBL_P = params[4]#1 # Quantas posições serão afetadas da solução corrente # Problema knapsack meuCusto = params[5]#1500 custos = params[6] ics = params[7] intermediarias = params[8] sIntermediarias = [] # Lista de listas com os ids de cada ics para fazer media geometrica gruposSegmentos = params[9] # Parte do knapsack, IC limite do alimentador ICLimite = params[10] # Tipo de problema, max(1-IC) [0] ou min(Custo) [1] tipoProblema = params[11] global avaliacoes avaliacoes = 0 ################ METODOS ############### def calculaICAlim(solucao): # Monta os vetores de segmento produtoAlim = 1 for i in range(0,len(gruposSegmentos)): produtoSeg = 1 for j in range(0,len(gruposSegmentos[i])): # Se está na solucao deve ser 1 if solucao[gruposSegmentos[i][j]]: produtoSeg = produtoSeg * 0.9999999 else: produtoSeg = produtoSeg * (1 - ics[gruposSegmentos[i][j]]) # pois ics na verdade é 1-IC mono.py #print 'produtoSeg = %f' % (produtoSeg) produtoSeg = pow(produtoSeg, 1/float(len(gruposSegmentos[i]))) produtoAlim = produtoAlim * produtoSeg return pow(produtoAlim, 1/float(len(gruposSegmentos))) def calculaPeso(s): peso = 0 for i in range(0,len(s)): if s[i]: peso = peso + custos[i] return peso def calculaValor(s): valor = 0 for i in range(0,len(s)): if s[i]: valor = valor + ics[i] return valor # Utilizando Subida (IC) randômico com o número de trocas fornecidas # Os vizinhos sao sempre trocas. S def buscaLocal(solucaoCorrente): global avaliacoes # Rodo iterMax vezes k = 0 # Armazeno o valor e peso atuais para não recalcular a todo momento valorCorrente = calculaValor(solucaoCorrente) pesoCorrente = calculaPeso(solucaoCorrente) valorBL = valorCorrente pesoBL = pesoCorrente # Encontrando um vizinho k qualquer s0 = d519.copy.copy(solucaoCorrente) while k < iterMaxBL: k = k+1 #j = 0 #while j < iterMaxBL_P: # Altera UMA posição # Mudo uma posicao pos = d519.randrange(0,len(s0)) if s0[pos]: s0[pos] = False valorBL = valorBL - ics[pos] pesoBL = pesoBL - custos[pos] else: s0[pos] = True valorBL = valorBL + ics[pos] pesoBL = pesoBL + custos[pos] avaliacoes = avaliacoes + 1 # RESTRIÇÃO: Verificando se a soma das trocas são válidas if tipoProblema == 0: if pesoBL > meuCusto: return solucaoCorrente else: if calculaICAlim(s0) < ICLimite: return solucaoCorrente if tipoProblema == 0: # Se sim, entao verifico qual tem IC melhor # Usar >= aqui pode implicar em loop infinito quando muito próximo do ótimo if valorBL > valorCorrente: solucaoCorrente = d519.copy.copy(s0) # nova solução corrente #valorCorrente = valorBL #s0 = d519.copy.copy(solucaoCorrente) else: if pesoBL < pesoCorrente: solucaoCorrente = d519.copy.copy(s0) return solucaoCorrente #[0]*len(solucaoCorrente) ################# MAIN ################# # Perturbacao: x posições da solucao p = pPert if p < 1: p = 1 # Há pelo menus uma pertubação # Monto a solucao de forma binaria s = [False]*len(ics) # Gerando a solução inicial: Aleatória ou Gulosa. Nao posso permitir que a solucao inicial extrapole muito a restricao, senao a perturbacao nunca encontrara uma solucao factivel # Aleatório if tipoProblema == 0: aleatorio = int(len(ics)*0.1) else: aleatorio = int(len(ics)*0.1) for i in range(0,aleatorio): s[d519.randrange(0,len(ics))] = True """ # Guloso for i in range(0,len(ics)): if ics[i]/float(custos[i]) > 3: s[i] = True """ # Nao deixa gerar solução inicial infactível if tipoProblema == 0: while calculaPeso(s) > meuCusto: s[d519.randrange(0,len(ics))] = 0 else: while calculaICAlim(s) < ICLimite: #print 'calculaICAlim(s) = %f' % (calculaICAlim(s)) s[d519.randrange(0,len(ics))] = 1 if debug: print 'Solução inicial:' print s print 'O IC da solucao inicial é %f' % (calculaValor(s)) print 'O preco da solucao inicial é %d' % (calculaPeso(s)) # busca local s com Best improvement s = buscaLocal(s) if debug: print 'Fim busca local' # Inicio loop ILS i = 0 while i < iterMaxILS: #if i == iterMaxILS - 1: # print 'VALOR FINAL: %f PESO FINAL: %f' % (calculaValor(s), calculaPeso(s)) #print 'Loop ILS %d' % (i) # Perturbacao: Gero um número n <= totalEquips*0.1 e esta será a qte de trocas a ser feita perturbacao = d519.copy.copy(s) for j in range(0,p): pos = d519.randrange(0,len(ics)) if perturbacao[pos]: perturbacao[pos] = False else: perturbacao[pos] = True # solucao qualquer pois buscaLocal irá cuidar disto #print n #print perturbacao # Faço novamente buscaLocal temp = buscaLocal(perturbacao) #temp = d519.copy.copy(perturbacao) if debug: print 'Executou busca local na iteracao %i do ILS' % (i) # Restrição (caso o perturbacao gerado tenha sido o ganhador na buscaLocal) if tipoProblema == 0: if calculaPeso(temp) > meuCusto: if debug: print 'Peso (%i) é maior que meuCusto (%i)' % (calculaPeso(temp),meuCusto) inserirBest = calculaValor(s) melhoresGeracao.append(inserirBest) if i in intermediarias: sIntermediarias.append(inserirBest) i = i+1 continue else: if calculaICAlim(temp) < ICLimite: inserirBest = calculaPeso(s) melhoresGeracao.append(inserirBest) if i in intermediarias: sIntermediarias.append(inserirBest) i = i+1 continue # Avalio o melhor if tipoProblema == 0: valorS = calculaValor(s) valorT = calculaValor(temp) if valorT > valorS: s = d519.copy.deepcopy(temp) melhoresGeracao.append(valorT) if i in intermediarias: sIntermediarias.append(valorT) else: melhoresGeracao.append(valorS) if i in intermediarias: sIntermediarias.append(valorS) else: pesoS = calculaPeso(s) pesoT = calculaPeso(temp) if pesoT < pesoS: s = d519.copy.deepcopy(temp) melhoresGeracao.append(pesoT) if i in intermediarias: sIntermediarias.append(pesoT) else: melhoresGeracao.append(pesoS) if i in intermediarias: sIntermediarias.append(pesoS) i = i+1 #print calculaValor(temp) #print calculaPeso(temp) if debug: print 'Solução final' print s print 'O IC da solucao final é %f' % (calculaValor(s)) print 'O preco da solucao final é %f' % (calculaPeso(s)) # Enquanto o critério de parada não for satisfeito # Perturbacao # Busca local na perturbacao # Verificar se s' melhor que s # Retorna resultado final #return [melhoresGeracao, intermediarias] #print s return [melhoresGeracao, sIntermediarias,avaliacoes]
mutacaoN = 5 pressaoSelN = 3 # Configuracoes SPEA2 geracoesS = 1000 tampopS = 50 crossoverS = 90 mutacaoS = 5 pressaoSelS = 3 # Configuracoes MACO colonias = 70 numForm = 20 # Constante inicial de ferormonio C = 1 Q = d519.randrange(11,100) alpha = 1 #27 beta = 1 rho = 0.7 #M = [92,4,43,83,84,68,92,82,6,44,32,18,56,83,25,96,70,48,14,58] #V = [44,46,90,72,91,40,75,35,8,54,78,40,77,15,61,17,75,29,75,63] #W = 878 # lista dos métodos a serem chamados algoritmos = [ 'multi_nsgaII','multi_spea2','multi_maco'] # nomes a serem plotados (caso False, o nome do algoritmo) #nomesAlg = ['mono_ils', 'mono_ga', 'mono_aco'] nomesAlg = ['multi_nsgaII','multi_spea2','multi_maco'] # lista de marcadores do matplotlib
def mono_ga(params): ########### PARAMETROS ########### global W, M, V, n, rho, gruposSegmentos, tipoProblema, ICLimite, avaliacoes # debug debug = params[0] # problem knapsack W = params[1] M = params[2] V = params[3] # Total itens n = len(M) # Numero de geracoes g = params[4] #600 # Tamanho populacao m = params[5] #150 # Probabilidade crossover crossover = params[6] #90 # Probabilidade mutacao mutacao = params[7] #5 # Pressão seletiva pS = params[8] #3 #Número de cortes para geração dos filhos cortes = params[9] #Número de buscas locais assim que nova população é gerada buscaLocal = params[10] # Posições das soluções intermediárias para justificar o ajuste de parâmetros intermediarias = params[11] sIntermediarias = [] # Lista de listas com os ids de cada ics para fazer media geometrica gruposSegmentos = params[12] # Parte do knapsack, IC limite do alimentador ICLimite = params[13] # Tipo de problema, max(1-IC) [0] ou min(Custo) [1] tipoProblema = params[14] melhoresGeracao = [ ] # a resposta do algoritmo, para cada geração uma única resposta será enviada avaliacoes = 0 # numero de avaliacoes de solucao objetivo # calcula rho estatico para usar na penalização rho = 0 for i in range(0, n): # calculo rho if V[i] / float(M[i]) > rho: rho = V[i] / float(M[i]) if debug: print 'Iniciou o algoritmo' # Crio os cromossomos e gero populacao 1 populacao = [False] * m if debug: print 'Instaciou população' for i in range(0, m): populacao[i] = Cromossomo(n) if debug: print 'Criou populacao' """ for i in range(0,m): print 'V[%d]: %f' % (i,populacao[i].valor) print 'M[%d]: %f' % (i,populacao[i].peso) raw_input('parou') """ # Seto o número de vezes em que a geração deu o mesmo resultado #mesmoResultado = 0 #ultimoResultado = 0 # Inicio as gerações for i in range(0, g): #i = 0 # para num avaliacoes #while i < g and avaliacoes < 210000: i = i + 1 if debug: print 'Inicio geração %d e calculou penalidade' % (i) """ for j in range(0,m): print populacao[j].alelos populacao[j].calculaPenalidade() print populacao[j].penalidade """ # Calcula penalidade da populacao for j in range(0, m): populacao[j].calculaPenalidade() # Crio vetor de nova populacao novaPop = [] # Crio uma cópia da população atual caso a nova não consiga solução factível popBkp = d519.copy.copy(populacao) # Verifico se vai entrar no crossover r = d519.randrange(0, 100) if r < crossover: if debug: print 'Entrou crossover' # Entrou no crossover, seleciono nova população a partir de torneio binário para seleção de pais # Devem ser 'm' tamanho da população de pais # O torneio selecionará dois cromossomos aleatórios e aquele que tiver maior fitness será o escolhido torneio = [] vencedorAnterior = -1 # para não deixar que dois pais sejam o mesmo pai j = 0 # Pressão seletiva: 2[2-5] while j < m: candidatos = [] for k in range(0, pS): candidato = d519.randrange(0, m) while candidato in candidatos or candidato == vencedorAnterior: candidato = d519.randrange(0, m) candidatos.append(candidato) if tipoProblema == 0: melhor = [0, 0] # [pos, val] else: melhor = [0, float('inf')] # [pos, pes] for k in range(0, pS): fitnessCandidato = populacao[ candidatos[k]].calculaFitness() if tipoProblema == 0: if fitnessCandidato > melhor[1]: melhor = [k, fitnessCandidato] else: if fitnessCandidato < melhor[1]: melhor = [k, fitnessCandidato] vencedorAnterior = candidatos[melhor[0]] torneio.append(candidatos[melhor[0]]) j = j + 1 if debug: print 'torneio: ' print torneio # Pais prontos em torneio, cruzamento de dois em dois j = 0 while j < m: # Antes de trabalhar com o ponto de corte, verifico se existe um pai acima de j (caso em que tamPop é ímpar) if len(torneio) % 2 == 1 and j == m - 1: novaPop.append(populacao[j]) break # Sai do while, o pai sozinho pode sofrer no máximo mutação # Gero dois filhos filho1 = Cromossomo(n, True) filho2 = Cromossomo(n, True) # Seleciono um ponto de cruzamento entre [0-n] (total alelos/itens) pontoCorte = d519.randrange(0, (n) * 2 + 1) # m+1 para englobar m ate = int(round(pontoCorte / float(2))) #Gerando primeira metade de filho1 e filho2 """ for k in range(0,ate): filho1.alelos[k] = populacao[torneio[j]].alelos[k] if filho1.alelos[k]: filho1.valor = filho1.valor + V[k] filho1.peso = filho1.peso + M[k] filho2.alelos[k] = populacao[torneio[j+1]].alelos[k] if filho2.alelos[k]: filho2.valor = filho2.valor + V[k] filho2.peso = filho2.peso + M[k] #Gerando segunda metade de filho1 e filho2 for k in range(ate,n): filho1.alelos[k] = populacao[torneio[j+1]].alelos[k] if filho1.alelos[k]: filho1.valor = filho1.valor + V[k] filho1.peso = filho1.peso + M[k] filho2.alelos[k] = populacao[torneio[j]].alelos[k] if filho2.alelos[k]: filho2.valor = filho2.valor + V[k] filho2.peso = filho2.peso + M[k] """ # INICIO C/ CORTES cortesV = [0] * cortes alpha = 1 inicio = 0 for l in range(0, cortes): cortesV[l] = d519.randrange(inicio + 1, n - cortes + alpha) alpha = alpha + 1 inicio = cortesV[l] atual = 0 tmp = 0 for l in range(0, cortes): # Alternando entre os pais if tmp % 2 == 0: pai1 = j pai2 = j + 1 else: pai1 = j + 1 pai2 = j for k in range(atual, cortesV[l]): filho1.alelos[k] = populacao[torneio[pai1]].alelos[k] if filho1.alelos[k]: filho1.valor = filho1.valor + V[k] filho1.peso = filho1.peso + M[k] filho2.alelos[k] = populacao[torneio[pai2]].alelos[k] if filho2.alelos[k]: filho2.valor = filho2.valor + V[k] filho2.peso = filho2.peso + M[k] atual = cortesV[l] tmp = tmp + 1 # Ultima parte for k in range(atual, n): filho1.alelos[k] = populacao[torneio[pai2]].alelos[k] if filho1.alelos[k]: filho1.valor = filho1.valor + V[k] filho1.peso = filho1.peso + M[k] filho2.alelos[k] = populacao[torneio[pai1]].alelos[k] if filho2.alelos[k]: filho2.valor = filho2.valor + V[k] filho2.peso = filho2.peso + M[k] # Inverte pais # FIM C/ CORTES if debug: print '===============' print 'torneio: ' print torneio print 'Pai1 (%d): ' % (torneio[j]) print populacao[torneio[j]].alelos print 'Pai2 (%d):' % (torneio[j + 1]) print populacao[torneio[j + 1]].alelos print 'Ponto de corte: %d' % (ate) print 'Filho1: ' print filho1.alelos print 'Filho2: ' print filho2.alelos print '===============' # Calculo valor e peso dos filhos #filho1.calculaValor() #filho2.calculaValor() #filho1.calculaPeso() #filho2.calculaPeso() avaliacoes = avaliacoes + 2 # Calculo dos dois filhos # Adiciono os filhos gerados na nova população novaPop.append(filho1) novaPop.append(filho2) j = j + 2 # Iniciou Elitismo # Se a melhor solucao de novaPop for pior que a melhor solucao de populacao, O(2N) # [pospopulacao, fitnesspopulacao, posnovapop, fitnessnovapop] if tipoProblema == 0: bests = [-1, 0, -1, 0] else: bests = [-1, float('inf'), -1, float('inf')] for j in range(0, m): fitness = populacao[j].calculaFitness() if tipoProblema == 0: if fitness > bests[1]: bests[0] = j bests[1] = fitness else: if fitness < bests[1]: bests[0] = j bests[1] = fitness # Computa penalidade, se existir novaPop[j].calculaPenalidade() fitness = novaPop[j].calculaFitness() if tipoProblema == 0: if fitness > bests[3]: bests[2] = j bests[3] = fitness else: if fitness < bests[3]: bests[2] = j bests[3] = fitness if tipoProblema == 0: if bests[1] > bests[3]: # Selecionar um membro aleatório de novaPop e adicionar o melhor de populacao novaPop[d519.randrange(0, m)] = populacao[bests[0]] else: if bests[1] < bests[3]: # Selecionar um membro aleatório de novaPop e adicionar o melhor de populacao novaPop[d519.randrange(0, m)] = populacao[bests[0]] # Fim Elitismo # Inicio mutação r = d519.randrange(0, 100) if r < mutacao: # Verifica se entrou no crossover if len(novaPop) == 0: novaPop = d519.copy.copy(populacao) if debug: print 'Entrou mutação' # Para cada indivíduo de novaPop, seleciono um bit aleatório e inverto o valor for j in range(0, m): bit = d519.randrange(0, n) if novaPop[j].alelos[bit]: novaPop[j].alelos[bit] = False novaPop[j].valor = novaPop[j].valor - V[bit] novaPop[j].peso = novaPop[j].peso - M[bit] else: novaPop[j].alelos[bit] = True novaPop[j].valor = novaPop[j].valor + V[bit] novaPop[j].peso = novaPop[j].peso + M[bit] avaliacoes = avaliacoes + 1 # Fim mutação #terminou crossover/mutacao if len(novaPop) != 0: populacao = d519.copy.copy(novaPop) # Atualiza população somente se gerou, pelo menos, uma solução factível. # Se não gerou solução alguma factível, a população não é atualizada popValida = False for j in range(0, m): if tipoProblema == 0: if populacao[j].peso <= W: # Aceita nova população popValida = True break else: if populacao[j].calculaICAlim() >= ICLimite: # Aceita nova população popValida = True break if not popValida: # Usa o backup populacao = popBkp # Procedimentos para fim geração # Busca local (diversidade) if buscaLocal > 0: # Para cada individuo da populacao, executo n buscas locais aleatórias for j in range(0, m): # altera ate buscaLocal posicoes aleatórias tmp = d519.copy.copy(populacao[j].alelos) tmpValues = [ d519.copy.copy(populacao[j].valor), d519.copy.copy(populacao[j].peso) ] for k in range(0, buscaLocal): pos = d519.randrange(0, n) if populacao[j].alelos[pos]: populacao[j].alelos[pos] = False populacao[j].valor = populacao[j].valor - V[pos] populacao[j].peso = populacao[j].peso - M[pos] else: populacao[j].alelos[pos] = True populacao[j].valor = populacao[j].valor + V[pos] populacao[j].peso = populacao[j].peso + M[pos] # Verifico NÃO se melhorou 'populacao' já alterada. # Lembrando: tmp é o original, populacao é o alterado if tipoProblema == 0: if populacao[j].valor < tmpValues[0] or populacao[ j].peso > W: # Volta populacao[j].alelos = tmp populacao[j].valor = tmpValues[0] populacao[j].peso = tmpValues[1] else: if populacao[j].peso > tmpValues[0] or populacao[ j].calculaICAlim() < ICLimite: # Volta populacao[j].alelos = tmp populacao[j].valor = tmpValues[0] populacao[j].peso = tmpValues[1] # Verifico quem é o melhor para adicionar em melhoresGeracao # Imprime melhor solução FACTÍVEL if tipoProblema == 0: best = [-1, 0, 0] else: best = [-1, float('inf'), 0] for j in range(0, m): valor = populacao[j].valor peso = populacao[j].peso if tipoProblema == 0: if valor > best[1] and peso <= W: best = [j, valor, peso] else: if peso < best[1] and populacao[j].calculaICAlim() >= ICLimite: best = [j, peso, valor] if best[0] == -1: for j in range(0, m): populacao[j].calculaPenalidade() if debug: print 'Nao obteve solução factível ):' # Como nenhuma solução é factível, recupero a com maior/menor fitness e vou retirando aleatoriamente até ela ser factível if tipoProblema == 0: populacao.sort(key=lambda x: x.calculaFitness(), reverse=True) while populacao[0].peso > W: tmp = d519.randrange(0, n) populacao[0].alelos[tmp] = False populacao[0].valor = populacao[0].valor - V[tmp] populacao[0].peso = populacao[0].peso - M[tmp] melhoresGeracao.append(populacao[0].valor) # Verifica se é para inserir nas soluções intermediárias if i in intermediarias: sIntermediarias.append(populacao[0].valor) else: populacao.sort(key=lambda x: x.calculaFitness(), reverse=False) while populacao[0].calculaICAlim() < ICLimite: tmp = d519.randrange(0, n) populacao[0].alelos[tmp] = True populacao[0].valor = populacao[0].valor + V[tmp] populacao[0].peso = populacao[0].peso + M[tmp] melhoresGeracao.append(populacao[0].peso) # Verifica se é para inserir nas soluções intermediárias if i in intermediarias: sIntermediarias.append(populacao[0].peso) else: melhoresGeracao.append(best[1]) if i in intermediarias: sIntermediarias.append(best[1]) if debug: print 'Fim da geração %d' % (i) # Imprime melhor solução FACTÍVEL if tipoProblema == 0: best = [-1, 0, 0] else: best = [-1, float('inf'), 0] for j in range(0, m): valor = populacao[j].valor peso = populacao[j].peso if tipoProblema == 0: if valor > best[1] and peso <= W: best = [j, valor, peso] else: if peso < best[1] and populacao[j].calculaICAlim() >= ICLimite: best = [j, peso, valor] if best[0] == -1: print 'Nao obteve solução factível ):' raw_input( 'Nao obteve solucao factivel. Pressione qualquer tecla para terminar ...' ) return 0 if debug: # Obteve solução factível e imprima a melhor (cromossomo) print '---------------' print 'Melhor solução no cromossomo %d: %f com peso %f' % ( best[0], best[1], best[2]) print populacao[best[0]].alelos #return populacao[best[0]].alelos return [melhoresGeracao, sIntermediarias, avaliacoes]