- Definição do Modelo de Dados
A classe Produto armazena as informações básicas e um identificador único.
class Produto:
def __init__(self, nome, categoria, prob_conversao):
self.nome = nome
self.categoria = categoria
# Probabilidade entre 0 e 1
self.prob_conversao = prob_conversao
def __repr__(self):
return f"{self.nome} ({self.prob_conversao*100}%)"
- Implementação do Sistema A*
Para que o A* funcione como um sistema de recomendação de "melhor caminho", definimos:Custo da Aresta ($g$): $1 - \text{probabilidade de conversão do destino}$. Quanto maior a chance de venda, menor o "custo" de transição.Heurística ($h$): Uma estimativa do custo restante. Para ser admissível, ela não pode subestimar o custo real.
import heapq
class AStarRecommendation:
def __init__(self, produtos):
self.produtos = produtos
def heuristica(self, atual, destino):
"""
Calcula o potencial de conversão restante.
Como o objetivo é chegar ao destino, a heurística foca na
relevância da categoria ou na diferença de conversão.
"""
if atual.categoria == destino.categoria:
return 0.1 # Categorias iguais sugerem proximidade
return 0.5
def encontrar_caminho(self, inicio, objetivo):
# Fila de prioridade: (f_score, produto_atual, caminho_percorrido)
open_set = []
heapq.heappush(open_set, (0, inicio, [inicio]))
# g_score: custo acumulado do início até o nó atual
g_score = {p: float('inf') for p in self.produtos}
g_score[inicio] = 0
while open_set:
_, atual, caminho = heapq.heappop(open_set)
if atual == objetivo:
return caminho
for vizinho in self.produtos:
if vizinho == atual:
continue
# Custo para mover para o vizinho (1 - prob para minimizar 'perda')
tentative_g_score = g_score[atual] + (1 - vizinho.prob_conversao)
if tentative_g_score < g_score[vizinho]:
g_score[vizinho] = tentative_g_score
f_score = tentative_g_score + self.heuristica(vizinho, objetivo)
heapq.heappush(open_set, (f_score, vizinho, caminho + [vizinho]))
return None
- Testando o Sistema
Vamos simular uma loja de eletrônicos onde queremos levar o usuário de um "Mouse" até um "Monitor Gamer".
# Criando produtos
p1 = Produto("Mouse Básico", "Periféricos", 0.9)
p2 = Produto("Mouse Pad RGB", "Acessórios", 0.7)
p3 = Produto("Teclado Mecânico", "Periféricos", 0.6)
p4 = Produto("Monitor Gamer 144Hz", "Monitores", 0.4)
p5 = Produto("Cabo HDMI Gold", "Acessórios", 0.8)
catalogo = [p1, p2, p3, p4, p5]
sistema = AStarRecommendation(catalogo)
# Executando a recomendação
caminho_otimo = sistema.encontrar_caminho(p1, p4)
print(f"Caminho de Recomendação Otimizado:")
for i, p in enumerate(caminho_otimo):
print(f"{i+1}. {p.nome} (Cat: {p.categoria})")
Por que usar A* aqui?
Diferente de uma recomendação simples baseada apenas em similaridade, o A* com essa lógica permite criar uma jornada de compra. Ele não apenas sugere o próximo item, mas planeja uma sequência de produtos que mantém o interesse do usuário (baixa resistência/custo) até chegar ao produto de maior valor ou objetivo final.