""" app/core/ranking.py — Kombiniertes Scoring (WP-04) Zweck: Zusammenführen von semantischem Score (normalisiert), Edge-Bonus und Centrality-Bonus in einen Gesamtscore für die Ergebnisreihung. Kompatibilität: Python 3.12+ Version: 0.1.0 (Erstanlage) Stand: 2025-10-07 Bezug: WP-04 Ranking-Formel (w_sem, w_edge, w_cent) Nutzung: from app.core.ranking import combine_scores Änderungsverlauf: 0.1.0 (2025-10-07) – Erstanlage. """ from __future__ import annotations from typing import List, Tuple, Dict def normalize_scores(values: List[float]) -> List[float]: """Min-Max-Normalisierung über die Kandidatenmenge (Fallback 0.5 bei Konstanz).""" if not values: return values lo, hi = min(values), max(values) if hi - lo < 1e-9: return [0.5] * len(values) return [(v - lo) / (hi - lo) for v in values] def combine_scores( hits: List[Tuple[str, float, dict]], # (id, semantic_score, payload) edge_bonus_map: Dict[str, float], centrality_map: Dict[str, float], w_sem: float = 0.70, w_edge: float = 0.25, w_cent: float = 0.05, ) -> List[Tuple[str, float, float, float, float]]: """ Liefert Liste von (point_id, total_score, edge_bonus, centrality_bonus, raw_semantic_score), absteigend nach total_score sortiert. """ sem = [h[1] for h in hits] sem_n = normalize_scores(sem) out = [] for (pid, s, payload), s_norm in zip(hits, sem_n): e = edge_bonus_map.get(pid, 0.0) c = centrality_map.get(pid, 0.0) total = w_sem * s_norm + w_edge * e + w_cent * c out.append((pid, total, e, c, s)) out.sort(key=lambda t: t[1], reverse=True) return out