Ejemplo n.º 1
0
 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
Ejemplo n.º 2
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]
Ejemplo n.º 3
0
 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]
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
########### 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]
Ejemplo n.º 7
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]
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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]