예제 #1
0
 def _limpa_construcao(self):
     self._tempo_construcao = RegistroTempo('Construção')
     tempo = RegistroTempo('Limpar solução anterior')
     self.solucao = Solucao(self.ambiente, self.matriz_conflito,
                            self.matriz_anuncio)
     self._lista_anuncio_disponivel = list(range(self.quantidade_anuncios))
     self._limpa_lista_tempo()
     self._limpa_dados_atuais()
예제 #2
0
 def _melhor_vizinho_adiciona(self, solucao: Solucao) -> Solucao:
     melhor = solucao
     melhor_encontrado = False
     for i in solucao.lista_anuncio_disponivel:
         solucao_adiciona = solucao.adiciona(i)
         if solucao_adiciona != None and solucao_adiciona.eh_melhor(melhor):
             # print(i, 'adicionado')
             melhor = solucao_adiciona
             melhor_encontrado = True
     return melhor if melhor_encontrado else None
예제 #3
0
 def _melhor_vizinho_substitui(self, solucao: Solucao) -> Solucao:
     melhor = solucao
     melhor_encontrado = False
     for i in solucao.lista_anuncio_adicionado:
         for j in solucao.lista_anuncio_disponivel:
             solucao_substitui = solucao.substitui(i, j)
             if solucao_substitui != None and solucao_substitui.eh_melhor(melhor):
                 # print(i, 'removido e', j, 'adicionado')
                 melhor = solucao_substitui
                 melhor_encontrado = True
     return melhor if melhor_encontrado else None
예제 #4
0
 def _melhor_vizinho_remaneja(self, solucao: Solucao) -> Solucao:
     melhor = solucao
     melhor_encontrado = False
     for i in solucao.lista_anuncio_adicionado:
         for quadro_i in solucao.matriz_anuncio_quadro[i]:
             for j in solucao.lista_anuncio_adicionado:
                 for quadro_j in solucao.matriz_anuncio_quadro[j]:
                     solucao_remaneja = solucao.remaneja(i, quadro_i, j, quadro_j)
                     if solucao_remaneja != None and solucao_remaneja.eh_melhor(melhor):
                         # print(i, 'no quadro', quadro_i, 'trocado com', j, 'do quadro', quadro_j)
                         melhor = solucao_remaneja
                         melhor_encontrado = True
     return melhor if melhor_encontrado else None
예제 #5
0
 def _melhor_vizinho_move(self, solucao: Solucao) -> Solucao:
     melhor = solucao
     melhor_encontrado = False
     for i in solucao.lista_anuncio_adicionado:
         for quadro_i in solucao.matriz_anuncio_quadro[i]:
             espaco_livre_suficiente_k = self._matriz_anuncio[i][TAMANHO]
             while espaco_livre_suficiente_k <= self._ambiente.tamanho_quadro:
                 for quadro_k in solucao.dicionario_espaco_quadro[espaco_livre_suficiente_k]:
                     solucao_move = solucao.move(i, quadro_i, quadro_k)
                     if solucao_move != None and solucao_move.eh_melhor(melhor):
                         # print(i, 'no quadro', quadro_i, 'movido para o quadro', quadro_k)
                         melhor = solucao_move
                         melhor_encontrado = True
                 espaco_livre_suficiente_k += 1
     return melhor if melhor_encontrado else None
예제 #6
0
 def limpa_solucao(self):
     self.solucao = Solucao(self.ambiente, self.matriz_conflito,
                            self.matriz_anuncio)
     self.lista_iteracao = []
예제 #7
0
class Guloso:

    quantidade_iteracoes = 1
    alpha = 0

    matriz_anuncio = None
    matriz_conflito = None
    ambiente = None

    tempo_total = None
    tempo_leitura = None
    tempo_solucao = None
    tempo_exibicao = None
    lista_tempo_construcao = None

    melhor_iteracao = None
    lista_iteracao = None

    construtor = None

    solucao: Solucao = None

    def __init__(self, caminho_instancia, ignora_conflitos=False):

        self.tempo_leitura = RegistroTempo('Tempo para ler entrada')
        self.tempo_solucao = RegistroTempo('Tempo para encontrar a solução',
                                           inicializa_agora=False)
        self.tempo_exibicao = RegistroTempo('Tempo para exibir a solução',
                                            inicializa_agora=False)
        self.tempo_total = RegistroTempo('Tempo total de execução')

        self.matriz_anuncio, self.ambiente, self.matriz_conflito = obtem_instancia(
            caminho_instancia)

        if ignora_conflitos:
            self.esvazia_conflito()

        self.tempo_leitura.finaliza()

        self.construtor = Construcao(self.matriz_anuncio, self.matriz_conflito,
                                     self.ambiente)

        print(f'\n{caminho_instancia}')
        self.exibe_instancia()

    def esvazia_conflito(self):
        for linha in self.matriz_conflito:
            for i in range(len(linha)):
                linha[i] = False

    def limpa_solucao(self):
        self.solucao = Solucao(self.ambiente, self.matriz_conflito,
                               self.matriz_anuncio)
        self.lista_iteracao = []

    def soluciona(self):

        self.inicializa_tempo()
        self.limpa_solucao()

        print('\n0%')
        for iteracao in range(self.quantidade_iteracoes):

            tempo_construcao = RegistroTempo()
            solucao_construida = self.construtor.constroi(self.alpha)
            self.lista_tempo_construcao.append(tempo_construcao.finaliza())

            solucao_atual = solucao_construida

            if solucao_atual.espaco_total_ocupado > self.solucao.espaco_total_ocupado:
                self.solucao = solucao_atual
                self.melhor_iteracao = iteracao
                if self.solucao.eh_otimo():
                    self.registra_iteracao(iteracao, solucao_construida,
                                           solucao_atual)
                    break

            self.registra_iteracao(iteracao, solucao_construida, solucao_atual)

            if EXIBE_SOLUCAO_DETALHE:
                print(f'\n{iteracao + 1}', '- solução:')
                print(solucao_atual.metricas())

                print('===================\n')
            print(np.round(100 * (iteracao + 1) / self.quantidade_iteracoes),
                  '%')

        self.tempo_solucao.finaliza()

        self.exibe_solucao()
        self.exibe_tempo()

        return self.solucao

    def inicializa_tempo(self):
        self.tempo_solucao.inicializa()
        self.lista_tempo_construcao = []

    def registra_iteracao(self, iteracao, solucao_construcao: Solucao,
                          solucao_busca_local: Solucao):
        linha_iteracao = [
            iteracao, solucao_construcao.espaco_total_ocupado,
            solucao_busca_local.espaco_total_ocupado,
            self.solucao.espaco_total_ocupado
        ]
        self.lista_iteracao.append(linha_iteracao)

    def exibe_tempo(self):
        if EXIBE_TEMPO:
            print('Quantidade de anúncios:', len(self.matriz_anuncio))

            if EXIBE_TEMPO_DETALHE:
                print()
                RegistroTempo.exibe_soma(self.lista_tempo_construcao,
                                         'Total Construção')

            self.tempo_leitura.exibe(ignora_inativacao=1)
            self.tempo_solucao.exibe(ignora_inativacao=1,
                                     nova_linha=(not EXIBE_SOLUCAO))

            if EXIBE_SOLUCAO:
                self.tempo_exibicao.exibe(nova_linha=1, ignora_inativacao=1)
            self.tempo_total.exibe(nova_linha=1, ignora_inativacao=1)

    def exibe_solucao(self):
        self.tempo_exibicao.inicializa()
        if EXIBE_SOLUCAO:
            print(f'\nSolução construída:\n{self.solucao}')
        if EXIBE_APROVEITAMENTO:
            print(self.solucao.avaliacao())
        self.tempo_exibicao.finaliza()

    def exibe_instancia(self):
        if EXIBE_INSTANCIA:
            print('Tamanho do quadro L:', self.ambiente.tamanho_quadro)
            print('Quantidade de quadros B:', self.ambiente.quantidade_quadros,
                  '\n')
            print('Anúncios A_i:\n', np.array(self.matriz_anuncio), '\n')
            print('Conflitos C_ij:')
            n = len(self.matriz_conflito)
            for i in range(6 if n > 6 else n):
                print('', self.matriz_conflito[i])
            if n > 6:
                print(' ...')
            print()

    def salva_solucao(self, local):
        arquivo = open(local, 'w+')
        arquivo_csv = csv.writer(arquivo)
        for quadro in self.solucao.matriz_solucao:
            arquivo_csv.writerow(quadro)
        arquivo.close()

    def salva_lista_iteracao(self, local):
        arquivo = open(local, 'w+')
        arquivo_csv = csv.writer(arquivo)
        for iteracao in self.lista_iteracao:
            arquivo_csv.writerow(iteracao)
        arquivo.close()
예제 #8
0
class Construcao:
    def __init__(self, matriz_anuncio, matriz_conflito, ambiente):

        self.matriz_anuncio = matriz_anuncio
        self.matriz_conflito = matriz_conflito
        self.ambiente: Ambiente = ambiente

        self.solucao = None

        self.quantidade_anuncios = len(matriz_anuncio)
        self._lista_anuncio_disponivel = None

        self._tempo_construcao = None
        self._lista_tempo_iteracao = None
        self._tempo_total_limites = None
        self._tempo_total_candidato = None
        self._tempo_total_first_fit = None

        self._limite_inferior_atual = None
        self._menor_ganho_atual = None
        self._maior_ganho_atual = None
        self._lista_indice_anuncio_candidato_atual = None
        self._tamanho_lista_indice_anuncio_candidato_atual = None

    def _limpa_construcao(self):
        self._tempo_construcao = RegistroTempo('Construção')
        tempo = RegistroTempo('Limpar solução anterior')
        self.solucao = Solucao(self.ambiente, self.matriz_conflito,
                               self.matriz_anuncio)
        self._lista_anuncio_disponivel = list(range(self.quantidade_anuncios))
        self._limpa_lista_tempo()
        self._limpa_dados_atuais()
        # tempo.exibe(1)

    def _limpa_dados_atuais(self):
        self._limite_inferior_atual = None
        self._menor_ganho_atual = None
        self._maior_ganho_atual = None
        self._lista_indice_anuncio_candidato_atual = None
        self._tamanho_lista_indice_anuncio_candidato_atual = None

    def _limpa_lista_tempo(self):
        self._lista_tempo_iteracao = [0] * self.quantidade_anuncios
        self._tempo_total_limites = 0
        self._tempo_total_candidato = 0
        self._tempo_total_first_fit = 0

    def constroi(self, aleatoriedade) -> Solucao:

        self._limpa_construcao()

        self._exibe_iteracao()

        for iteracao in range(self.quantidade_anuncios):

            tempo_iteracao = RegistroTempo()

            self._atualiza_limite_inferior_atual(aleatoriedade)

            indice_selecionado = self._obtem_candidato()

            self._insere_first_fit(indice_selecionado)

            self._exibe_iteracao(iteracao, indice_selecionado)

            self._lista_anuncio_disponivel.remove(indice_selecionado)

            self._lista_tempo_iteracao[iteracao] = tempo_iteracao.finaliza()

        self._exibe_dados_tempo()

        return self.solucao

    def _obtem_candidato(self):

        tempo_candidatos = RegistroTempo()

        if self._lista_indice_anuncio_candidato_atual == None:
            self._atualiza_lista_indice_anuncio_candidato()

        indice_selecionado = self._escolhe_candidato()

        self._tempo_total_candidato = self._tempo_total_candidato + tempo_candidatos.finaliza(
        )

        return indice_selecionado

    def _atualiza_limite_inferior_atual(self, aleatoriedade):

        tempo_limites = RegistroTempo()

        if self._maior_ganho_atual == None or self._menor_ganho_atual == None or self._limite_inferior_atual == None:

            self._atualiza_menor_e_maior_ganhos_disponiveis_atuais()

            self._limite_inferior_atual = self._maior_ganho_atual - aleatoriedade * (
                self._maior_ganho_atual - self._menor_ganho_atual)

            self._lista_indice_anuncio_candidato_atual = None

        self._tempo_total_limites = self._tempo_total_limites + tempo_limites.finaliza(
        )

    def _exibe_dados_tempo(self):
        if EXIBE_TEMPO:
            print(f'\nQuantidade de iterações: {self.quantidade_anuncios}\n')

            print(
                f'Média por iteração: {round(np.average(self._lista_tempo_iteracao) * 100, 1)} ms'
            )
            print(
                f'Iteração mais rápida: {round(np.min(self._lista_tempo_iteracao) * 100, 1)} ms'
            )
            print(
                f'Iteração mais lenta: {round(np.max(self._lista_tempo_iteracao) * 100, 1)} ms\n'
            )

            print(
                f'Tempo total limites: {round(self._tempo_total_limites, 2)} s'
            )
            print(
                f'Tempo total candidatos: {round(self._tempo_total_candidato, 2)} s'
            )
            print(
                f'Tempo total first fit: {round(self._tempo_total_first_fit, 2)} s\n'
            )

            self._tempo_construcao.exibe(1)

    def _atualiza_menor_e_maior_ganhos_disponiveis_atuais(self):

        tempo = RegistroTempo('Obter limites de ganho')
        menor_ganho = self.matriz_anuncio[
            self._lista_anuncio_disponivel[0]][GANHO]
        maior_ganho = self.matriz_anuncio[
            self._lista_anuncio_disponivel[0]][GANHO]

        for i in self._lista_anuncio_disponivel[1:]:
            ganho = self.matriz_anuncio[i][GANHO]
            if ganho < menor_ganho:
                menor_ganho = ganho
            elif ganho > maior_ganho:
                maior_ganho = ganho

        self._menor_ganho_atual = menor_ganho
        self._maior_ganho_atual = maior_ganho
        # tempo.exibe()

    def _atualiza_lista_indice_anuncio_candidato(self):
        tempo = RegistroTempo('Obter candidatos')
        lista_indice = []
        tamanho_lista = 0
        for i in self._lista_anuncio_disponivel:
            anuncio = self.matriz_anuncio[i]
            if anuncio[GANHO] >= self._limite_inferior_atual:
                lista_indice.append(i)
                tamanho_lista = tamanho_lista + 1
        self._lista_indice_anuncio_candidato_atual = lista_indice
        self._tamanho_lista_indice_anuncio_candidato_atual = tamanho_lista
        # tempo.exibe(1)

    def _escolhe_candidato(self):

        indice_sorteado = rd.randint(
            0, self._tamanho_lista_indice_anuncio_candidato_atual - 1)
        indice_candidato = self._lista_indice_anuncio_candidato_atual.pop(
            indice_sorteado)

        tamanho_candidato = self.matriz_anuncio[indice_candidato][GANHO]

        if tamanho_candidato == self._maior_ganho_atual:
            self._maior_ganho_atual = None

        if tamanho_candidato == self._menor_ganho_atual:
            self._menor_ganho_atual = None

        self._tamanho_lista_indice_anuncio_candidato_atual = self._tamanho_lista_indice_anuncio_candidato_atual - 1

        return indice_candidato

    def _insere_first_fit(self, indice_candidato):

        tempo = RegistroTempo('First Fit')
        candidato = self.matriz_anuncio[indice_candidato]
        frequencia_anuncio = candidato[FREQUENCIA]

        lista_indice_quadro_selecionado = []
        contagem_quadros = 0

        for indice_quadro in self.solucao.lista_quadro_disponivel:
            if self.solucao.copia_pode_ser_inserida(indice_candidato,
                                                    indice_quadro):
                lista_indice_quadro_selecionado.append(indice_quadro)
                contagem_quadros = contagem_quadros + 1
                if contagem_quadros == frequencia_anuncio:
                    self.solucao.insere(lista_indice_quadro_selecionado,
                                        indice_candidato)
                    break

        self._tempo_total_first_fit = self._tempo_total_first_fit + tempo.finaliza(
        )
        # tempo.exibe(1)

    def _exibe_iteracao(self, iteracao=None, candidato_selecionado=None):
        if EXIBE_ITERACAO:

            if iteracao != None:
                print(f'\nIteração {iteracao + 1}:')

            df_anuncio = DataFrame(self.matriz_anuncio,
                                   columns=['Tamanho', 'Frequencia', 'Ganho'])

            print('\nAnúncios disponíveis C:')
            print(df_anuncio.filter(self._lista_anuncio_disponivel, axis=0))

            if self._limite_inferior_atual != None:
                print(f'\nLimite inferior: {self._limite_inferior_atual}')

            if self._lista_indice_anuncio_candidato_atual != None:
                print(f'\nCandidatos RC:')
                print(
                    df_anuncio.filter(
                        self._lista_indice_anuncio_candidato_atual, axis=0))

            if candidato_selecionado != None:
                print('\nCandidato selecionado A_j:')
                print(df_anuncio.filter([candidato_selecionado], axis=0))

            print('\nSolução parcial S:')
            print(
                DataFrame(self.solucao.matriz_solucao,
                          columns=['Espaço ocupado', 'Anúncios inseridos']))

            print('\n==================================\n')