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}")