import heapq
from typing import List, Dict, Tuple, Optional
class Produto:
def __init__(self, name: str, categoria: str, prob_conversao: float):
self.name = name
self.categoria = categoria
self.prob_conversao = prob_conversao
def __repr__(self):
return f"Produto('{self.name}', '{self.categoria}', {self.prob_conversao})"
class AStarRecommendation:
def __init__(self, produtos: List[Produto]):
self.produtos = produtos
self.map: Dict[str, Produto] = {p.name: p for p in produtos}
def get(self, name: str) -> Optional[Produto]:
return self.map.get(name)
def neighbors(self, p: Produto) -> List[Produto]:
return [x for x in self.produtos if x is not p]
def custo(self, atual: Produto, v: Produto) -> float:
return 1 - v.prob_conversao
def heuristica(self, atual: Produto, obj: Produto) -> float:
return 1 - atual.prob_conversao
def reconstruir(self, veio: Dict[Produto, Produto], atual: Produto) -> List[Produto]:
c = [atual]
while atual in veio:
atual = veio[atual]
c.append(atual)
return list(reversed(c))
def encontrar(self, ini: str, obj: str) -> Tuple[List[Produto], float]:
inicio, objetivo = self.get(ini), self.get(obj)
if not inicio or not objetivo:
raise ValueError("Produto não encontrado.")
aberta = []
heapq.heappush(aberta, (0.0, inicio))
veio = {}
g = {p: float("inf") for p in self.produtos}
g[inicio] = 0.0
f = {p: float("inf") for p in self.produtos}
f[inicio] = self.heuristica(inicio, objetivo)
fechada = set()
while aberta:
_, atual = heapq.heappop(aberta)
if atual in fechada: continue
if atual is objetivo:
return self.reconstruir(veio, atual), g[atual]
fechada.add(atual)
for v in self.neighbors(atual):
if v in fechada: continue
tent = g[atual] + self.custo(atual, v)
if tent < g[v]:
veio[v] = atual
g[v] = tent
f[v] = tent + self.heuristica(v, objetivo)
heapq.heappush(aberta, (f[v], v))
return [], float("inf")
if __name__ == "__main__":
produtos = [
Produto("Notebook Gamer X", "notebook", 0.80),
Produto("Notebook Ultrafino Y", "notebook", 0.70),
Produto("Smartphone Z", "smartphone", 0.90),
Produto("Fone Bluetooth Pro", "audio", 0.75),
Produto("Monitor 27'' 144Hz", "monitor", 0.65),
Produto("Teclado Mecânico RGB", "periférico", 0.60),
]
sistema = AStarRecommendation(produtos)
inicio = "Notebook Gamer X"
objetivo = "Fone Bluetooth Pro"
caminho, custo = sistema.encontrar(inicio, objetivo)
print("=== Recomendação A* ===")
print("Caminho:")
for p in caminho:
print(f"- {p.name} ({p.prob_conversao})")
print("Custo:", custo)