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

import heapq


class Produto:
    """Representa um produto do catálogo da loja."""

    def __init__(self, nome, categoria, probabilidade_conversao):
        self.nome = nome
        self.categoria = categoria
        self.probabilidade_conversao = probabilidade_conversao  # valor entre 0 e 1

    def __repr__(self):
        return f"{self.nome} ({self.categoria}, conv={self.probabilidade_conversao:.2f})"

    def __lt__(self, other):
        # necessário para o heapq desempatar quando os f_score são iguais
        return self.nome < other.nome


class AStarRecommendation:
    """Sistema de recomendação de produtos usando o algoritmo A*."""

    def __init__(self, produtos):
        self.produtos = produtos
        self.grafo = self._construir_grafo()

    def _construir_grafo(self):
        """
        Grafo simplificado: cada produto se conecta a todos os outros.
        Custo(A -> B) = 1 - probabilidade_conversao(B).
        Recomendar um produto com alta conversão é 'barato';
        recomendar um produto pouco provável de compra é 'caro'.
        """
        grafo = {p: [] for p in self.produtos}
        for origem in self.produtos:
            for destino in self.produtos:
                if origem is not destino:
                    custo = 1 - destino.probabilidade_conversao
                    grafo[origem].append((destino, custo))
        return grafo

    def heuristica(self, produto, objetivo):
        """
        h(n): estima o custo restante usando a probabilidade
        de conversão do próprio produto atual.
        """
        return 1 - produto.probabilidade_conversao

    def encontrar_melhor_caminho(self, inicio, objetivo):
        """Algoritmo A* para achar o melhor caminho de recomendação."""
        open_set = []
        heapq.heappush(open_set, (0, inicio))

        veio_de = {}
        g_score = {p: float('inf') for p in self.produtos}
        g_score[inicio] = 0

        f_score = {p: float('inf') for p in self.produtos}
        f_score[inicio] = self.heuristica(inicio, objetivo)

        aberto_set_produtos = {inicio}

        while open_set:
            _, atual = heapq.heappop(open_set)
            aberto_set_produtos.discard(atual)

            if atual is objetivo:
                return self._reconstruir_caminho(veio_de, atual), g_score[atual]

            for vizinho, custo in self.grafo[atual]:
                g_tentativo = g_score[atual] + custo
                if g_tentativo < g_score[vizinho]:
                    veio_de[vizinho] = atual
                    g_score[vizinho] = g_tentativo
                    f_score[vizinho] = g_tentativo + self.heuristica(vizinho, objetivo)
                    if vizinho not in aberto_set_produtos:
                        heapq.heappush(open_set, (f_score[vizinho], vizinho))
                        aberto_set_produtos.add(vizinho)

        return None, float('inf')  # não encontrou caminho

    def _reconstruir_caminho(self, veio_de, atual):
        caminho = [atual]
        while atual in veio_de:
            atual = veio_de[atual]
            caminho.append(atual)
        caminho.reverse()
        return caminho


# ---------------------------------------------------------
# Testando o sistema
# ---------------------------------------------------------
if __name__ == "__main__":
    produto1 = Produto("Notebook Gamer", "Eletrônicos", 0.30)
    produto2 = Produto("Mouse sem fio", "Acessórios", 0.85)
    produto3 = Produto("Cadeira Gamer", "Móveis", 0.55)
    produto4 = Produto("Headset Bluetooth", "Acessórios", 0.75)
    produto5 = Produto("Monitor 144Hz", "Eletrônicos", 0.40)

    produtos = [produto1, produto2, produto3, produto4, produto5]
    sistema = AStarRecommendation(produtos)

    caminho, custo_total = sistema.encontrar_melhor_caminho(produto1, produto5)

    print("Melhor caminho de recomendação encontrado:")
    for p in caminho:
        print(f"  -> {p}")
    print(f"Custo total do caminho: {custo_total:.2f}")
1 resposta

Oi, Bruna. Tudo bem com você?

Gostei da forma como você implementou o sistema de recomendação utilizando o algoritmo A*. Sua solução contempla os principais requisitos da atividade, com a criação da classe Produto, da classe AStarRecommendation, da heurística baseada na probabilidade de conversão e do teste utilizando diferentes produtos. Também ficou interessante a escolha de representar o custo das conexões como 1 - probabilidade_conversao, pois isso faz com que produtos com maior chance de conversão sejam naturalmente priorizados durante a busca.

Além disso, a organização do código facilita a leitura, com métodos bem separados para construção do grafo, cálculo da heurística e reconstrução do caminho. O uso do heapq para gerenciar a fila de prioridade também está adequado ao funcionamento do algoritmo.

Se você limitasse as conexões apenas entre produtos de categorias semelhantes, como imagina que isso impactaria o caminho encontrado pelo algoritmo A* e a qualidade das recomendações?

Parabéns pelo desenvolvimento da atividade e por compartilhar sua solução. Continue praticando e utilizando o fórum sempre que surgir uma nova dúvida. Estamos à disposição para ajudar.

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