- Definindo os produtos:
class Produto:
def __init__(self, nome, categoria, probabilidade_conversao):
self.nome = nome
self.categoria = categoria
self.probabilidade_conversao = probabilidade_conversao
def __repr__(self):
return f"Produto(Nome='{self.nome}', Categoria='{self.categoria}', Conversão={self.probabilidade_conversao:.2f})"
def __lt__(self, other):
# Usado para comparação de prioridade em filas
return self.probabilidade_conversao > other.probabilidade_conversao # maior conversão quer dizer 'menor' comportamento de topo de pilha
- Criando sistema de recomendação e Implementando a heurística
import heapq
class AStarRecommendation:
def __init__(self, produtos):
self.produtos = {p.nome: p for p in produtos}
self.grafo = self._construir_grafo_simplificado(produtos)
def _construir_grafo_simplificado(self, produtos):
# Grafo completo onde cada produto se conecta a todos os outros
grafo = {produto.nome: [] for produto in produtos}
for i, p1 in enumerate(produtos):
for j, p2 in enumerate(produtos):
if p1.nome != p2.nome:
# Suponha que o "custo" para ir de um produto para outro seja 1
# No A*, o custo real (g) é a distância percorrida.
# Podemos ajustar este custo para refletir alguma similaridade ou dificuldade.
# Por simplicidade, faremos custo de transição como 1 para todos.
grafo[p1.nome].append((p2.nome, 1)) # (destino, custo)
return grafo
def _heuristica(self, produto_nome):
# Heurística baseada na probabilidade de conversão
# Queremos minimizar o "custo", então uma probabilidade de conversão alta deve resultar em um valor heurístico baixo.
# Uma forma de fazer isso é 1 - probabilidade_conversao, ou simplesmente usar a probabilidade negativa.
# Como o A* busca o menor custo total, e queremos maximizar a conversão, a heurística deve ser
# um *custo estimado* para alcançar o objetivo. Vamos usar (1 - probabilidade_conversao) como um "custo" potencial.
# Ou, para ser mais direto com o problema, vamos considerar que um produto com alta conversão é "mais próximo" do objetivo ideal.
# Para um caminho de recomendação, o custo seria a "desvantagem" ou "distância" do produto ideal.
# Portanto, quanto maior a probabilidade de conversão, menor o valor da heurística.
return 1 - self.produtos[produto_nome].probabilidade_conversao
def encontrar_melhor_caminho(self, inicio_nome, objetivo_nome):
if inicio_nome not in self.produtos or objetivo_nome not in self.produtos:
return None, "Produto de início ou objetivo não encontrado."
# Fila de prioridade: (f_score, g_score, produto_atual_nome, caminho)
# f_score = g_score + h_score
# g_score = custo do início até o produto atual
# h_score = estimativa heurística do produto atual até o objetivo
fila_prioridade = [(0 + self._heuristica(inicio_nome), 0, inicio_nome, [inicio_nome])]
# Manter o menor g_score encontrado para cada produto
g_scores = {produto: float('inf') for produto in self.produtos}
g_scores[inicio_nome] = 0
# Para reconstruir o caminho
caminhos = {inicio_nome: [inicio_nome]}
while fila_prioridade:
f_score_atual, g_score_atual, atual_nome, caminho_atual = heapq.heappop(fila_prioridade)
if atual_nome == objetivo_nome:
return caminho_atual, f"Custo total (aproximado): {f_score_atual:.2f}"
# Se já encontramos um caminho melhor para este nó, ignoramos
if g_score_atual > g_scores[atual_nome]:
continue
for vizinho_nome, custo_transicao in self.grafo[atual_nome]:
tentative_g_score = g_score_atual + custo_transicao
if tentative_g_score < g_scores[vizinho_nome]:
g_scores[vizinho_nome] = tentative_g_score
caminhos[vizinho_nome] = caminho_atual + [vizinho_nome]
h_score = self._heuristica(vizinho_nome)
f_score = tentative_g_score + h_score
heapq.heappush(fila_prioridade, (f_score, tentative_g_score, vizinho_nome, caminhos[vizinho_nome]))
return None, "Caminho não encontrado."
Continua nos comentários