Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

1
resposta

Faça como eu fiz: construindo um sistema inteligente de recomendação

from dataclasses import dataclass, field
import heapq
 
 
@dataclass
class Produto:
    nome: str
    categoria: str
    taxa_conversao: float  # entre 0 e 1
 
    def __hash__(self):
        return hash(self.nome)
 
    def __repr__(self):
        return f"{self.nome} [{self.categoria}] ({self.taxa_conversao:.0%})"
 
 
class SistemaRecomendacaoAStar:
    """Encontra a sequência de produtos mais 'promissora' entre um
    produto de partida e um produto-alvo, usando o algoritmo A*."""
 
    def __init__(self, catalogo):
        self.catalogo = catalogo
        self.conexoes = self._montar_conexoes()
 
    def _montar_conexoes(self):
        # Cada produto se conecta a todos os demais do catálogo.
        # O custo da aresta é a diferença absoluta entre as taxas
        # de conversão: quanto mais parecidas, mais barato o passo.
        conexoes = {}
        for origem in self.catalogo:
            vizinhos = []
            for destino in self.catalogo:
                if origem is destino:
                    continue
                custo = abs(origem.taxa_conversao - destino.taxa_conversao)
                vizinhos.append((destino, custo))
            conexoes[origem] = vizinhos
        return conexoes
 
    @staticmethod
    def _heuristica(produto_atual, produto_alvo):
        # Estimativa de quão longe ainda estamos do alvo: quanto mais
        # próximas as taxas de conversão, menor a heurística.
        return abs(produto_atual.taxa_conversao - produto_alvo.taxa_conversao)
 
    def buscar_melhor_rota(self, origem, destino):
        contador = 0  # desempate estável na fila de prioridade
        fronteira = [(self._heuristica(origem, destino), contador, origem, 0)]
        veio_de = {}
        custo_ate_aqui = {origem: 0}
        explorados = set()
 
        while fronteira:
            _, _, atual, g_atual = heapq.heappop(fronteira)
 
            if atual in explorados:
                continue
            explorados.add(atual)
 
            if atual == destino:
                return self._reconstruir_rota(veio_de, destino)
 
            for vizinho, custo_aresta in self.conexoes[atual]:
                novo_g = g_atual + custo_aresta
                if vizinho not in custo_ate_aqui or novo_g < custo_ate_aqui[vizinho]:
                    custo_ate_aqui[vizinho] = novo_g
                    f = novo_g + self._heuristica(vizinho, destino)
                    contador += 1
                    heapq.heappush(fronteira, (f, contador, vizinho, novo_g))
                    veio_de[vizinho] = atual
 
        return None  # não encontrou caminho (não deveria acontecer em grafo completo)
 
    @staticmethod
    def _reconstruir_rota(veio_de, destino):
        rota = [destino]
        while rota[-1] in veio_de:
            rota.append(veio_de[rota[-1]])
        rota.reverse()
        return rota
 
 
if __name__ == "__main__":
    catalogo = [
        Produto("Fone Bluetooth", "Eletrônicos", 0.92),
        Produto("Carregador Portátil", "Eletrônicos", 0.81),
        Produto("Mochila Notebook", "Acessórios", 0.68),
        Produto("Garrafa Térmica", "Casa", 0.55),
    ]
 
    sistema = SistemaRecomendacaoAStar(catalogo)
 
    origem = catalogo[0]    # Fone Bluetooth
    destino = catalogo[2]   # Mochila Notebook
 
    rota = sistema.buscar_melhor_rota(origem, destino)
 
    print(f"Melhor rota de recomendação entre '{origem.nome}' e '{destino.nome}':")
    for produto in rota:
        print(" ->", produto)
1 resposta

Oi, Everton. Tudo bem com você?

Obrigado por compartilhar a sua implementação do sistema inteligente de recomendação utilizando o algoritmo A*. Analisei o código e ele atende aos requisitos propostos na atividade. A classe Produto foi definida com os atributos solicitados, o grafo conecta os produtos do catálogo, a heurística utiliza a taxa de conversão como critério de estimativa e a busca retorna a melhor rota entre os produtos informados. Também foi interessante utilizar heapq para a fila de prioridade e um contador para desempate, deixando a execução mais consistente.

Uma dica que pode enriquecer ainda mais o projeto é experimentar diferentes critérios para o custo das arestas ou para a heurística. Por exemplo, além da taxa de conversão, seria possível considerar fatores como similaridade de categoria, histórico de compras ou avaliações dos clientes, aproximando o exemplo de um sistema de recomendação utilizado em aplicações reais.

Quais outros atributos você incluiria nos produtos para tornar esse sistema de recomendação ainda mais inteligente e próximo de um cenário real?

Parabéns pelo desenvolvimento da atividade e por compartilhar sua solução. Continue praticando e utilizando o fórum sempre que desejar trocar ideias ou esclarecer dúvidas. Estaremos à disposição para ajudar.

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!