File size: 8,407 Bytes
639f871
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
"""
config.py — Configurazione centralizzata del progetto tour_ga.

Tutte le costanti "magiche" del progetto sono raccolte qui.
I moduli importano da questo file invece di avere valori hardcoded.

Struttura:
  TRANSPORT  — velocità, overhead, soglie di modalità
  FITNESS    — pesi obiettivi, penalità, normalizzazione
  REPAIR     — vincoli di riparazione genetica
  SEEDING    — parametri costruzione popolazione iniziale
  GA         — default algoritmo evolutivo
  VISUALIZER — colori e stili per la mappa HTML
"""
from __future__ import annotations

# ============================================================
# TRANSPORT — Modello di percorrenza realistico
# ============================================================

# Fattore correttivo Haversine → percorso stradale reale
# 1.0 = linea d'aria, 1.3 = stima tipica percorso urbano
ROUTE_DETOUR_FACTOR: float = 1.3

# Soglia sotto la quale, anche in modalità MIXED, si usa v_walk
# (600 m → preferisce a piedi rispetto al mezzo)
MIXED_THRESHOLD_M: int = 600

# Soglia sotto la quale non conviene prendere il mezzo in TRANSIT
# (prendere bus/metro per <400m è più lento del cammino)
TRANSIT_WALK_THRESHOLD_KM: float = 0.40

# Overhead fisso per ogni tratta in mezzo pubblico (minuti)
# Comprende: cammino alla fermata + attesa mezzo + cammino dalla fermata
# Roma: bus ~8-12 min freq., metro ~4-5 min freq. → media 10 min
TRANSIT_OVERHEAD_MIN: int = 10

# Overhead fisso per ogni tratta in auto/taxi (minuti)
# Comprende: ricerca parcheggio + cammino dal parcheggio
CAR_OVERHEAD_MIN: int = 5

# Velocità medie di percorrenza in km/h (escluso overhead)
# Chiave: (TransportMode.value, MobilityLevel.value)
SPEED_KMH: dict[tuple[str, str], float] = {
    ("walk",    "normal"):  4.5,
    ("walk",    "limited"): 3.0,
    ("car",     "normal"):  25.0,
    ("car",     "limited"): 25.0,
    ("transit", "normal"):  20.0,   # metro Roma in media ~20 km/h
    ("transit", "limited"): 16.0,
    ("mixed",   "normal"):  4.5,    # segmenti brevi → v_walk
    ("mixed",   "limited"): 3.0,
}

# Velocità per segmenti lunghi in modalità MIXED (oltre MIXED_THRESHOLD_M)
MIXED_LONG_SPEED_KMH: dict[str, float] = {
    "normal":  20.0,
    "limited": 16.0,
}

# ============================================================
# FITNESS — Funzione di valutazione multi-obiettivo
# ============================================================

# Pesi default per la funzione scalare aggregata
W_SCORE: float = 0.50   # peso obiettivo score (da massimizzare)
W_DIST:  float = 0.20   # peso obiettivo distanza (da minimizzare)
W_TIME:  float = 0.30   # peso penalità tempo (non usato nello scalare diretto)

# Penalità per sforamento budget (per ora di sforamento)
PENALTY_BUDGET_OVERRUN: float = 50.0

# Penalità scalare per slot pasto non coperto
# Applicata solo se "restaurant" è nelle categorie ammesse dal profilo
PENALTY_MEAL_MISSING: float = 0.25

# Soglia di attesa cumulata (minuti) sotto cui non si penalizza
# Attese brevi (es. 3 min prima dell'apertura) sono accettabili
WAIT_PENALTY_THRESHOLD_MIN: int = 5

# Fattore di penalità per i minuti di attesa eccedenti la soglia
# (per ora di attesa cumulata oltre la soglia)
WAIT_PENALTY_FACTOR: float = 10.0

# Cap moltiplicativo per effective_score con boost da tag_weights
# Evita che tag boost portino lo score molto sopra 1.0
SCORE_BOOST_CAP: float = 1.5

# Distanza massima di normalizzazione per la fitness (km)
# Dipende dalla modalità di trasporto
MAX_DIST_WALK_KM:    float = 15.0
MAX_DIST_TRANSIT_KM: float = 50.0
MAX_DIST_CAR_KM:     float = 80.0

# Minuti di visita extra per ogni membro del gruppo oltre il primo
GROUP_VISIT_OVERHEAD_PER_PERSON: int = 5

# Fitness utilization bonus
FITNESS_UTILIZATION_BONUS_FACTOR : float = 0.3

# ============================================================
# REPAIR — Vincoli del motore di riparazione genetica
# ============================================================

# Attesa massima tollerata per qualsiasi PoI (minuti)
# PoI che richiederebbero un'attesa maggiore vengono rimossi dal tour
MAX_WAIT_MIN: int = 30

# Tolleranza di attesa speciale per l'inserimento di ristoranti
# nei slot pasto: arrivare poco prima dell'apertura è comportamento normale
MEAL_SLOT_WAIT_OVERRIDE_MIN: int = 45

# Fraction della lunghezza del tour usata nell'ordinamento per
# spostare i ristoranti nella posizione temporalmente corretta
# (non una costante numerica, ma un commento di design)

# ============================================================
# SEEDING — Costruzione della popolazione iniziale
# ============================================================

# Frazione di individui costruiti con greedy deterministico
SEED_GREEDY_FRACTION: float = 0.20

# Frazione di individui costruiti con α-greedy perturbato
SEED_PERTURBED_FRACTION: float = 0.20

# Il restante (1 - greedy - perturbed) viene costruito casualmente e riparato

# Range del parametro alpha per l'α-greedy perturbato
# alpha=0 → greedy puro; alpha=0.5 → semi-casuale (GRASP-like)
SEED_ALPHA_MIN: float = 0.15
SEED_ALPHA_MAX: float = 0.50   # alpha_min + 0.35

# Dimensione della Restricted Candidate List come frazione dei candidati
# (top RCL_FRACTION vengono estratti casualmente invece del migliore assoluto)
RCL_FRACTION: float = 0.20

# ============================================================
# PASTI - Valori di default
# ============================================================

# --- Preferenze pasti ---
WANT_LUNCH:             bool = True
WANT_DINNER:            bool = False
LUNCH_TIME:             int  = 720
DINNER_TIME:            int  = 1140
MEAL_WINDOW:            int  = 60
MAX_BAR_STOPS:          int = 1
MAX_GELATERIA_STOPS:    int = 1
MEAL_RESERVE_MIN:       int  = 90
EVENING_THRESHOLD:      int  = 1140   # 19:00

# ============================================================
# GA — Default dell'algoritmo evolutivo (usati da SolverConfig)
# ============================================================

GA_POP_SIZE:         int   = 80
GA_MAX_GENERATIONS:  int   = 300
GA_CX_PROB:          float = 0.85    # probabilità di crossover
GA_MUT_PROB:         float = 0.20    # probabilità di mutazione
GA_TOURNAMENT_K:     int   = 3       # candidati per torneo
GA_STAGNATION_LIMIT: int   = 50      # generazioni senza miglioramento → stop
GA_MAX_WAIT_MIN:     int   = MAX_WAIT_MIN   # propagato al RepairEngine
GA_OX_CROSSOVER_PROB: float = 0.60
# Probabilità di usare Order Crossover (OX) vs PoI-aware crossover,
# condizionata all'aver già deciso di fare crossover (cx_prob).
# OX è più conservativo (preserva ordine globale),
# PoI-aware è più espolorativo (scambia blocchi per categoria).
# Un mix 60/40 bilancia convergenza ed esplorazione tematica.
# Orario di partenza e budget default (minuti dalla mezzanotte)

DEFAULT_START_TIME: int = 540    # 09:00
DEFAULT_BUDGET:     int = 480    # 8 ore

# Coordinate default (Roma, centro storico)
DEFAULT_START_LAT: float = 41.8960
DEFAULT_START_LON: float = 12.4840

# ============================================================
# VISUALIZER — Stili per la mappa HTML interattiva
# ============================================================

# Colori hex per categoria PoI sulla mappa
# Basati sui ramp del design system del progetto
CATEGORY_COLORS: dict[str, str] = {
    "museum":     "#7F77DD",   # purple-400
    "monument":   "#378ADD",   # blue-400
    "restaurant": "#D85A30",   # coral-400
    "bar":        "#BA7517",   # amber-400
    "gelateria":  "#D4537E",   # pink-400
    "park":       "#639922",   # green-400
    "viewpoint":  "#1D9E75",   # teal-400
}

# Colori speciali per elementi della mappa
MAP_ROUTE_COLOR:     str = "#378ADD"   # polyline del percorso
MAP_START_COLOR:     str = "#1D9E75"   # marker punto di partenza
MAP_ARROW_COLOR:     str = "#5F5E5A"   # frecce di direzione

# Opacità della polyline del percorso (0.0–1.0)
MAP_ROUTE_OPACITY: float = 0.75

# Spessore della polyline in pixel
MAP_ROUTE_WEIGHT: int = 4

# Raggio dei cerchi marker in pixel
MAP_MARKER_RADIUS: int = 10

# Zoom default sulla mappa al caricamento
MAP_ZOOM_DEFAULT: int = 14

# URL tiles OpenStreetMap (nessuna API key richiesta)
MAP_TILE_URL: str = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
MAP_TILE_ATTRIBUTION: str = (
    '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
)