Come è costruita la piattaforma, su cosa gira, dove stanno i dati, come si tiene in piedi e che cosa ancora non fa. Documento destinato alla valutazione tecnica: descrive il sistema in esercizio, non una proposta.
Questo documento descrive l'architettura, il funzionamento, la sicurezza e i limiti di Lane, la piattaforma su cui gira il servizio di bus a chiamata descritto nella presentazione.
È scritto per chi deve giudicare la solidità tecnica di un sistema, non per chi deve usarlo: l'uso è descritto nei manuali operativi del servizio. Qui si risponde a domande diverse: su cosa poggia, chi possiede i dati, cosa succede quando qualcosa si rompe, quanto regge, come si esce.
Il documento non contiene la parte economica, che è oggetto separato, né impegni contrattuali o livelli di servizio: quelli si definiscono, se c'è interesse, in un secondo momento e sui parametri dell'ente. Contiene invece, al capitolo 14, i limiti noti del sistema. Sono dichiarati di proposito: un sistema in esercizio da poche settimane che non avesse limiti sarebbe un sistema descritto male.
L'appendice A entra nel dettaglio del motore del bus a chiamata: formulazione del problema, funzione di costo, decisioni architetturali con le alternative scartate, misure con le procedure per riprodurle.
Tutti i numeri riportati sono misurati sul codice e sulla configurazione in esercizio alla data del documento, non stimati. Le misure dell'appendice riportano ciascuna la propria data.
01 Perimetro funzionale
02 Architettura del sistema
03 Le tre interfacce
04 Il motore del bus a chiamata
05 Il motore stradale
06 Dati: cosa, dove, di chi
07 Sicurezza
08 Continuità del servizio
09 Capacità e prestazioni
10 Verifica e non-regressione
11 Trasparenza e controllo dell'ente
12 Integrazioni
13 Manutenzione ed evoluzione
14 Limiti noti e punti aperti
15 Reversibilità e uscita
16 Glossario
A Il motore del bus a chiamata in dettaglio
Lane è una piattaforma unica che gestisce più servizi di mobilità sullo stesso impianto: stessa anagrafica, stesso motore di autorizzazioni, stessa contabilità, stesse app. I servizi non sono prodotti separati messi vicini, sono configurazioni dello stesso sistema. Questo ha una conseguenza pratica per l'ente: il bus a chiamata non è un prototipo isolato, è un servizio dentro un impianto che già porta traffico reale su altri fronti.
| Servizio | Cosa fa | Stato |
|---|---|---|
| Taxi e NCC | Corsa singola da A a B, immediata o programmata, con classi di veicolo, tariffe per area, tratte a prezzo fisso, assegnazione all'autista e ciclo completo fino al pagamento. | In esercizio |
| Commissioni | Incarichi affidati a un autista: ritiro e consegna di un oggetto, acquisto per conto del cliente, invio di un pacco. Comprende i giri multi-pacco con manifesto di bordo. | In esercizio |
| Bus a chiamata | Trasporto pubblico condiviso senza orari fissi: il cittadino prenota, il sistema decide quale mezzo lo prende, in che ordine e con chi lo mette insieme. È il servizio approfondito ai capitoli 04 e 05. | Pronto all'esercizio |
I quattro ruoli hanno interfacce separate e permessi separati. Un operatore vede e governa solo i propri mezzi, i propri conducenti, le proprie corse e i propri numeri: non ha visibilità su quelli di altri operatori. L'isolamento è imposto dal server a ogni richiesta, non dalla schermata.
| Componente | Tecnologia | Ruolo |
|---|---|---|
| Backend | PHP 8.3, Laravel 12.43 | Cuore del sistema: tutte le regole, tutti gli stati, tutte le decisioni. Le app non decidono nulla da sole. |
| Base dati | MySQL 8 | Dato di verità: anagrafiche, corse, pagamenti, contabilità, configurazione. 229 migrazioni versionate. |
| Cache e code | Redis | Cache applicativa e coda dei lavori differiti: invio notifiche, email, elaborazioni. |
| Motore stradale | GraphHopper, Java 21 | Tempi e percorsi reali su strada. Installato sul nostro server, non un servizio esterno a consumo. |
| Tempo reale | Google Firebase | Posizione dei mezzi, stato della corsa, messaggi fra cliente e conducente. Solo dati volatili. |
| Notifiche | OneSignal, Firebase Cloud Messaging | Avvisi push ai telefoni. |
| App | Flutter, Dart 3.4 | Una base di codice per iOS e Android. Due app distinte: cittadino e conducente. |
| Server web | nginx, PHP-FPM | Esposizione HTTPS con certificato a rinnovo automatico. |
| Sistema | Ubuntu 24.04 LTS | Server dedicato in datacenter nell'Unione Europea (Germania). |
Non è una misura di qualità, ma di ordine di grandezza: serve a capire di che cosa si parla quando si dice "piattaforma".
| Misura | Valore |
|---|---|
| Codice backend | 393 file PHP, circa 59.000 righe |
| Schermate del pannello e della consolle | 303 viste |
| Punti di ingresso applicativi | 432 rotte web, 151 endpoint API |
| Evoluzioni della base dati | 229 migrazioni versionate |
| Codice delle due app | 310 file Dart, circa 93.500 righe |
| Versione delle app alla data | 1.0.15 (build 20), cittadino e conducente allineate |
Nessuna regola vive dentro l'app. Il passaggio di stato di una corsa è validato da una macchina a stati sul server, che conosce quali transizioni sono lecite per ogni tipo di servizio: una corsa non può passare a "passeggero sceso" se non risulta salito, un conducente non può dichiarare un'assenza del cliente se il server non vede che era sul posto e ha atteso i minuti previsti. Questo rende il sistema robusto agli errori delle app e alle manomissioni, e permette di correggere una regola aggiornando il server, senza aspettare che tutti abbiano aggiornato il telefono.
L'algoritmo che abbina passeggeri e mezzi è isolato dietro un contratto interno. Oggi è una euristica di inserimento; domani può diventare un algoritmo diverso, più sofisticato, senza toccare il resto del sistema. La stessa disciplina vale per il motore stradale e per il gateway di pagamento. Non è un dettaglio estetico: è ciò che rende la piattaforma aggiornabile senza riscritture.
È il posto di lavoro della centrale. Non è una vista in sola lettura: da qui si governa il servizio.
Disponibile per iOS e Android. Accesso con numero di telefono verificato o con account Google; non richiede la creazione di una password. Mostra solo i servizi effettivamente disponibili nel punto in cui si trova l'utente, secondo le aree di servizio configurate. Per il bus a chiamata: ricerca della fermata più vicina con distanza e minuti a piedi, prenotazione immediata o anticipata, seguito del mezzo in avvicinamento, avvisi di cambio orario. Sei lingue.
Disponibile per iOS e Android, in lingua italiana. Gestisce il turno, riceve gli incarichi, guida il conducente passo per passo nelle salite e nelle discese, conferma le salite con un codice, invia la posizione al sistema. Il conducente aziendale non modifica il proprio profilo: le credenziali le imposta la centrale, e questo evita che un'azienda perda il controllo dei propri accessi.
È la parte del sistema che decide, ogni volta che qualcuno prenota, quale mezzo lo prende, in che ordine e insieme a chi. È anche la parte più delicata: un servizio di questo tipo si giudica sul tempo di attesa e sulla lunghezza del viaggio, e sono entrambi conseguenze di questa decisione.
Un taxi è semplice: un'auto, un cliente, da A a B. Un bus a chiamata condiviso è un problema diverso, noto in letteratura come dial-a-ride: più passeggeri sullo stesso mezzo, ognuno con origine e destinazione proprie, vincoli di attesa e di durata da rispettare per ciascuno, e la necessità di rispondere in tempo reale. È un problema di ottimizzazione combinatoria che non si risolve in forma esatta nei tempi di una richiesta web: si risolve bene con euristiche.
Il motore non stabilisce da sé che cosa sia accettabile. I vincoli sono parametri, visibili e modificabili dalla centrale, con effetto immediato sulle decisioni successive.
| Leva | Cosa governa |
|---|---|
| Attesa massima | Quanto può aspettare un passeggero prima della salita. |
| Allungamento massimo | Di quanto può allungarsi il viaggio di chi è già a bordo per far salire qualcun altro. |
| Durata massima a bordo | Tetto alla durata del singolo viaggio. |
| Sosta alla fermata | Tempo fermo per salita e discesa: si somma agli orari promessi, quindi le promesse restano oneste anche con molte fermate. |
| Capienza | Posti del mezzo, con conteggio separato dei posti per carrozzina. |
| Anticipo di prenotazione | Con quanto anticipo si può prenotare, e da quanto prima una prenotazione anticipata entra nei piani operativi. |
Il senso di questa architettura è che il compromesso fra comodità per il cittadino e costo per l'ente diventa esplicito e misurabile. Stringere le leve migliora il servizio percepito e richiede più mezzi; allargarle riduce il costo e peggiora l'esperienza. Con lo strumento di simulazione la centrale vede l'effetto prima di applicarlo, sulla domanda reale già registrata.
| Processo | Frequenza | Cosa fa |
|---|---|---|
| Ri-ottimizzazione | Ogni minuto | Rivede i piani dei mezzi, sposta le richieste non ancora a bordo sul mezzo migliore e fa partire le richieste rimaste in coda appena si libera un posto. Le prenotazioni anticipate entrano nei piani quando il loro orario si avvicina, non prima. |
| Registro dei turni | Ogni 10 minuti | Tiene il conto delle ore di servizio effettive di ogni mezzo, con chiusura automatica all'ultima posizione nota se un turno resta aperto. |
| Sentinella del motore stradale | Ogni 5 minuti | Verifica che il motore stradale risponda e lo segnala nel registro degli eventi se non risponde. |
| Matrice dei tempi | Ogni notte, 03:30 | Aggiorna la tabella dei tempi fra le fermate, calcolando solo le coppie mancanti. |
| Pulizia di fine giornata | Ogni notte, 04:00 | Chiude richieste, giri e turni rimasti appesi, perché il giorno dopo il motore riparta su dati puliti. |
| Calibrazione degli orari | Ogni lunedì, 04:00 | Confronta le durate effettive con quelle promesse negli ultimi 30 giorni e corregge il fattore di stima, per operatore. |
La pulizia notturna non cancella niente. Chiude gli stati e scrive un evento con il motivo. Lo storico resta integro e le statistiche restano oneste: se una richiesta è scaduta, nei numeri del mese risulta scaduta, non sparisce. Non tocca mai un passeggero risultante a bordo, né una prenotazione futura, né uno stato già definitivo. Eseguita due volte di fila non cambia nulla.
La calibrazione degli orari è volutamente prudente. Interviene solo con un campione minimo, e il fattore correttivo è limitato entro una banda stretta. Un algoritmo che si auto-corregge senza freni, su pochi dati, è un algoritmo che a un certo punto promette orari assurdi.
Per decidere bene servono i minuti veri su strada vera. A San Marino questo pesa più che altrove: su un territorio in pendenza due fermate vicine in linea d'aria possono essere lontane in auto, per via di tornanti, sensi unici e dislivelli. Una stima puramente geometrica, qui, sbaglia in modo sistematico.
Il motore stradale è GraphHopper, software libero, installato sul nostro server come servizio di sistema. Non è un servizio esterno a pagamento per chiamata. Tre conseguenze concrete:
Il profilo di percorrenza di serie di un motore stradale presume un'auto alla velocità consentita su ogni strada: sulle strade collinari sammarinesi dà tempi troppo brevi. Il profilo in uso è tarato per il minibus su 120 coppie di fermate confrontate con i tempi di Google Maps. Sulle 101 coppie in cui i due sistemi percorrono le stesse strade lo scarto medio per coppia è sceso dal 20,6% al 10,1%, e la somma dei tempi coincide. Nelle altre 19 i due sistemi scelgono strade diverse e il confronto non è significativo.
Le fermate sono un insieme finito e stabile. Perciò i tempi fra ogni coppia di fermate sono calcolati una volta sola e conservati: 239.610 tratte, corrispondenti alle circa 490 fermate caricate. Il motore, mentre decide, non interroga mai la rete: legge una tabella. È la ragione per cui il dispatch risponde in tempi da interfaccia e non da elaborazione.
Il servizio non si ferma. Nell'ordine:
Questa è una scelta di progetto ricorrente nel sistema e vale la pena esplicitarla: degradare, non fermarsi. Quando una dipendenza esterna viene meno, il sistema perde qualità, non funzione.
Per un ente pubblico questa è la sezione che conta più di tutte. La risposta breve: i dati del servizio sono dell'ente, stanno in Unione Europea, sono esportabili in formato aperto in qualsiasi momento senza chiedere nulla a noi.
| Categoria | Dove risiede | Note |
|---|---|---|
| Anagrafica dei cittadini | Base dati MySQL, server in Germania | Nome, contatto, storico delle corse. Protetta da autenticazione, mai esposta ai client. |
| Anagrafica conducenti e mezzi | Base dati MySQL | Con i documenti caricati dall'azienda. |
| Corse, richieste, turni, eventi | Base dati MySQL | Ogni cambio di stato lascia un evento datato con il motivo. |
| Movimenti e contabilità | Base dati MySQL | Incassi, compensi, fatture, note di liquidazione. |
| Posizione dei mezzi in tempo reale | Google Firebase | Coordinate, direzione, velocità, orario. Cancellate a fine turno. |
| Stato corsa e messaggi | Google Firebase | Vive per la durata della corsa. Serve a far aggiornare le schermate senza interrogare continuamente il server. |
La separazione è voluta e va letta così: in Firebase non c'è anagrafica. Ci sono dati volatili di posizione e di stato. I dati personali stanno nella base dati, dietro autenticazione, sul nostro server.
Nella consolle, senza passare da noi e senza richiesta formale, l'operatore esporta:
Sono formati aperti, leggibili da qualunque foglio di calcolo o sistema informativo. Non c'è alcun passaggio che richieda la nostra collaborazione. Il capitolo 15 spiega cosa succede in caso di interruzione del rapporto.
Lo storico di esercizio non ha oggi una cancellazione automatica: le corse restano. Le cancellazioni automatiche previste riguardano dati accessori e sono selettive: le registrazioni di conducenti rimaste incomplete oltre sette giorni vengono rimosse insieme ai loro documenti; i gettoni di accesso scaduti vengono eliminati ogni cinque minuti; i registri tecnici vengono ruotati.
La base dati, i documenti caricati e il motore stradale risiedono su un server dedicato in Germania. I servizi accessori di Google, ossia il tempo reale e le mappe, e il servizio di notifiche push sono fornitori con infrastruttura anche extraeuropea: attraverso di loro transitano posizioni dei mezzi, identificativi tecnici dei dispositivi e testo delle notifiche, non l'anagrafica. La collocazione esatta di questi servizi va dichiarata nel registro dei trattamenti dell'ente: siamo in grado di fornire il dettaglio, ed è un adempimento da fare, non una formalità da rimandare.
Le app comunicano con il server tramite gettoni personali a scadenza, non con credenziali memorizzate. I gettoni scaduti vengono eliminati automaticamente.
È il punto che merita più attenzione, perché è quello che in molti sistemi resta aperto. Le regole di accesso ai dati in tempo reale sono state chiuse e verificate in esercizio. In sintesi:
Le regole sono versionate nel codice sorgente insieme al resto: sono ricostruibili e ispezionabili, non una configurazione lasciata in una console.
Il pannello e la consolle non caricano alcuna libreria da fornitori esterni: tutto il materiale necessario è servito dal nostro server. La decisione è nata da un problema di prestazioni, ma l'effetto più importante è un altro: la centrale non dipende dalla disponibilità di fornitori terzi per aprire una pagina, e nessun fornitore esterno osserva chi apre quale schermata. Le sole eccezioni sono le mappe e gli strumenti di pagamento, che per loro natura sono servizi remoti.
| Misura | Stato |
|---|---|
| Copia della base dati | Ogni notte, conservata per 14 giorni. |
| Copia dei documenti caricati | Ogni settimana, conservata per 28 giorni. |
| Riavvio automatico dei servizi | Motore stradale e coda dei lavori ripartono da soli se cadono. |
| Sentinella | Controllo periodico del motore stradale con traccia nel registro. |
| Pulizia notturna | Il servizio riparte ogni giorno su dati coerenti. |
| Rinnovo dei certificati | Automatico. |
| Se viene meno | Cosa succede al servizio |
|---|---|
| Il motore stradale | Il servizio continua sulla tabella dei tempi e sulla stima tarata. Peggiora la precisione, non si ferma. Il servizio riparte da solo. |
| Il tempo reale | Le app tornano a interrogare il server periodicamente. Il seguito del mezzo diventa meno fluido, prenotazioni e assegnazioni non ne risentono. |
| Le notifiche push | Le corse funzionano. Il cittadino vede gli aggiornamenti aprendo l'app; la centrale può avvisare per telefono. |
| La rete di un conducente | L'app riallinea lo stato alla riconnessione. Il registro dei turni si chiude da solo all'ultima posizione nota, quindi le ore restano corrette. |
| Il server | Il servizio si ferma. È il punto scoperto: si veda il capitolo 14. |
È un principio di progetto, non un ripiego. In ogni punto in cui il sistema decide da solo, la centrale può intervenire a mano: prenotare per chi telefona, assegnare d'autorità una richiesta a un mezzo, segnare una salita o una discesa al posto del conducente, mettere in pausa un mezzo, riassegnare un mezzo in emergenza creando il turno da remoto, annullare una richiesta con un motivo tracciato. Un servizio pubblico non può dipendere dal fatto che l'automatismo abbia sempre ragione.
La reattività del dispatch non è un effetto della potenza del server, ma di due scelte precise. La prima: durante una decisione il motore non interroga mai la rete, legge la tabella dei tempi. La seconda: configurazioni, rotte e pagine sono precompilate, quindi il costo fisso di ogni richiesta è quasi azzerato.
Il costo del ciclo di ri-ottimizzazione è tenuto piatto anche in condizioni di saturazione prolungata: quando la coda non riesce a essere smaltita, il ciclo si ferma dopo un numero fisso di tentativi consecutivi senza esito, invece di riprovare all'infinito. È una protezione introdotta dopo aver misurato un caso reale di domanda doppia, non una precauzione teorica.
Il sistema è dimensionato per il territorio sammarinese. Una simulazione di capacità condotta sul motore vero ha indicato, con quattro mezzi e le leve impostate sui valori di allora, un tetto dell'ordine di alcune centinaia di corse al giorno. Il numero dipende interamente da quanti mezzi sono in turno e da come sono regolate le leve: è esattamente la domanda a cui risponde lo strumento di simulazione della consolle, che lavora sulla domanda reale già registrata e non su ipotesi.
La domanda giusta non è "avete testato", è "come fate a sapere che una modifica di oggi non rompe il servizio di domani".
Esiste un comando che fa girare il motore vero su scenari deterministici, dentro una transazione che viene annullata alla fine: nessun residuo nella base dati, nessuna notifica inviata. Controlla tre cose:
Le funzioni sono verificate con collaudi completi sul sistema in esercizio, condotti con elenchi di controllo scritti prima e con esito registrato punto per punto: ciclo di vita della corsa taxi, ciclo del giro commissioni con il relativo conto, impianto amministrativo. Sono collaudi su ambiente reale, non su simulazioni.
Un servizio pubblico deve poter essere controllato da chi lo paga e osservato da chi lo usa. Sono due esigenze diverse e il sistema le tiene separate.
Esiste una pagina pubblica di trasparenza del servizio, raggiungibile senza alcun accesso, che espone l'andamento reale. Non è una vetrina: è il riconoscimento che, per un servizio pagato con risorse pubbliche, i numeri sono di chi lo finanzia.
Nelle schermate destinate alla centrale e ai cittadini non compaiono sigle tecniche, e i cruscotti numerici sono accompagnati da una spiegazione in lingua corrente. Al cittadino, inoltre, non viene mai comunicato un tempo di attesa calcolato al minuto, ma una fascia. Un orario preciso che poi slitta produce più danno di una fascia onesta rispettata: è una regola di prodotto che abbiamo scelto e che manteniamo anche quando il dato preciso sarebbe disponibile.
La piattaforma espone già oggi una interfaccia applicativa strutturata, quella che usano le due app: 151 punti di accesso autenticati e versionati. La stessa interfaccia è la base naturale per un collegamento con i sistemi dell'ente.
| Integrazione | Stato |
|---|---|
| Esportazione dati verso sistemi dell'ente | Disponibile subito in formato aperto, anche in modo programmato. |
| Anagrafiche del servizio | Fermate, orari, mezzi e turni sono già governati dalla consolle; un caricamento massivo da un sistema esterno è un lavoro circoscritto. |
| Sistemi di bigliettazione o titoli di viaggio | Non presente. È un intervento nuovo, da valutare sulla base del sistema in uso. |
| Pubblicazione dei dati in standard di trasporto pubblico | Non presente. Tecnicamente alla portata partendo dai dati già strutturati di fermate e corse. |
| Identità digitale dell'ente | Non presente. L'impianto di autenticazione è modulare e predisposto ad accogliere un fornitore di identità esterno. |
Le tre voci non presenti sono indicate come tali di proposito. Sono lavori possibili, non funzioni esistenti, e vanno valutate per quello che sono.
Lo sviluppo e la manutenzione sono di Titano Dev Studio. Il codice è interamente versionato in un repository con la storia completa delle modifiche: ogni intervento è tracciato, datato e reversibile. La configurazione dei server e le procedure di rilascio sono documentate nel repository stesso.
I rilasci sono incrementali e non richiedono la sospensione del servizio. La sequenza è fissa: aggiornamento del codice, applicazione delle evoluzioni della base dati, rigenerazione delle cache, riavvio dei processi in coda. Le evoluzioni della base dati sono descritte in file versionati e applicate in ordine: lo stato della base dati è ricostruibile da zero.
Le app si aggiornano attraverso i negozi. Il sistema è progettato perché questo non sia un vincolo operativo: poiché le regole vivono sul server, una modifica di regola ha effetto immediato su tutti, anche su chi non ha ancora aggiornato. Le app si aggiornano quando cambia quello che si vede o si tocca, non quando cambia una regola.
Il servizio di bus a chiamata, nella configurazione attuale, non movimenta denaro. La piattaforma, per gli altri servizi, ha invece un impianto di pagamento digitale completo, costruito con un principio: esiste un punto unico del sistema in cui nasce un pagamento, qualunque sia il modo in cui la carta viene raccolta. Il pagamento in viaggio è un blocco dell'importo, non un addebito: se la corsa si annulla il blocco si scioglie e non c'è alcun rimborso da gestire. I rimborsi, quando servono, avvengono sempre in forma di credito riutilizzabile.
L'attivazione commerciale dei pagamenti dipende da una decisione societaria e normativa ancora aperta, indipendente da questa valutazione. Lo scriviamo perché fa parte dello stato reale del sistema.
Questo capitolo elenca ciò che oggi non c'è o non regge. È la parte del documento che consigliamo di leggere per prima, e ogni voce ha accanto quello che serve per chiuderla.
Tutto gira su un server dedicato. Non c'è ridondanza: un guasto grave della macchina ferma il servizio fino al ripristino, e il ripristino richiede la ricostruzione del server e il riversamento delle copie. È il limite più rilevante del sistema allo stato attuale. Un esercizio con obblighi di continuità richiede un secondo nodo e un tempo di ripristino concordato: è un intervento infrastrutturale noto e dimensionabile, e va messo sul tavolo insieme ai livelli di servizio.
Le copie automatiche della base dati e dei documenti risiedono sullo stesso server. Proteggono dall'errore umano e dal danno logico, non dalla perdita della macchina. La copia fuori sede è il primo intervento da fare e ha costo e complessità modesti: lo indichiamo come lavoro da pianificare, non come opzione.
Come descritto al capitolo 10: la rete di sicurezza copre il motore, non ogni funzione periferica.
Il tempo reale e le notifiche poggiano su servizi di Google e su un fornitore di notifiche. Il sistema degrada in modo controllato se vengono meno, come descritto al capitolo 08, ma la dipendenza esiste e va dichiarata. Il motore stradale, che è la dipendenza più critica per il bus a chiamata, è invece installato in casa proprio per non averne una.
Le due app sono distribuite tramite i canali di prova dei negozi. La pubblicazione aperta è una decisione di tempi.
Prima di un esercizio reale vanno formalizzati: titolarità e responsabilità del trattamento, finalità e base giuridica, tempi di conservazione dello storico, informativa ai cittadini, registro dei trattamenti con il dettaglio dei fornitori. Il sistema è in grado di applicare le regole che l'ente stabilisce; le regole, oggi, non sono state stabilite.
Un ente non deve firmare nulla che non sappia come disfare. Per questo la posizione è scritta qui, prima di qualunque trattativa.
Quello che non è reversibile è il software: resta di Titano Dev Studio. La distinzione è quella normale fra i dati, che sono dell'ente, e lo strumento, che è del fornitore. Qualunque ipotesi diversa, dalla licenza d'uso perpetua alla consegna del codice sorgente, è materia di trattativa e va detta prima, non dopo.
Questa appendice è per chi deve valutare l'algoritmo e le scelte che lo circondano. Riprende e aggiorna la relazione di architettura di agosto 2026, che sostituisce.
L'assegnazione è un problema di raccolta e consegna con finestre temporali e vincoli di capacità, noto in letteratura come pickup and delivery problem with time windows, nella variante dinamica: le richieste arrivano mentre i mezzi sono in servizio con passeggeri a bordo. È un problema NP-difficile, e le decisioni già eseguite, cioè i passeggeri saliti, non sono revocabili: vincolano lo spazio delle soluzioni successive.
L'approccio è un'euristica di inserimento con enumerazione completa delle posizioni, seguita da un raffinamento locale con guardia di non peggioramento e da una ri-ottimizzazione periodica delle sole richieste non ancora servite. L'inserimento dà una risposta entro il tempo di una richiesta; la ri-ottimizzazione recupera ciò che l'inserimento perde per l'ordine in cui le richieste arrivano.
Usare la differenza invece del totale è determinante. Il totale favorirebbe sempre i mezzi meno carichi, disperdendo la domanda e riducendo le corse condivise; la differenza misura quanto la richiesta costa davvero al servizio, e rende conveniente mettere insieme passeggeri compatibili. Il peso q sceglie fra piani già ammissibili: non interviene sui vincoli.
Il supplemento di 180 secondi riguarda il passeggero a cui è già stato comunicato un mezzo: un altro mezzo lo prende solo se il guadagno supera tre minuti. Evita che il passeggero si veda cambiare mezzo per vantaggi trascurabili. Quando il cambio avviene, il passeggero viene avvisato.
Il ciclo gira in un'unica transazione, e chi è a bordo non viene mai spostato. In saturazione prolungata il ciclo smette di ritentare la coda dopo dieci insuccessi consecutivi, mentre chi aveva già un piano viene sempre ricollocato: il costo del ciclo resta piatto anche quando la domanda supera a lungo la capacità.
| Grandezza | Espressione | Ordine di grandezza reale |
|---|---|---|
| Coppie di posizioni per mezzo | (n+1)(n+2)/2 = O(n²) | Circa 90 per un giro di 12 tappe. |
| Costo di un candidato | O(n) | Ricostruzione della linea del tempo. |
| Costo per mezzo | O(n³) | — |
| Costo totale | O(V · n³) | Alcune centinaia di piani valutati sull'intera flotta. |
Il termine cubico è sostenibile perché n, il numero di tappe di un giro, è limitato dalla capienza del mezzo e dalla finestra di A.2, non dal volume complessivo delle richieste. L'enumerazione resta completa, senza potature.
Un solo tratto non sta nella tabella dei tempi: quello fra la posizione istantanea del mezzo e la sua prima tappa, che dipende da dove si trova il mezzo in quel momento. Per questo tratto si usa una stima geometrica, con coefficienti diversi per fascia di distanza in linea d'aria.
| Distanza in linea d'aria | Secondi al metro | Velocità efficace | Allungamento del percorso |
|---|---|---|---|
| fino a 500 m | 0,2032 | 17,7 km/h | 1,966 |
| 500 m – 1 km | 0,1957 | 18,4 km/h | 1,966 |
| 1 – 2 km | 0,1734 | 20,8 km/h | 1,739 |
| 2 – 4 km | 0,1598 | 22,5 km/h | 1,654 |
| 4 – 8 km | 0,1435 | 25,1 km/h | 1,540 |
| oltre 8 km | 0,1356 | 26,5 km/h | 1,417 |
Il gradiente segue la morfologia della rete: sui tratti brevi pesano tornanti e ripartenze, su quelli lunghi si viaggia. I coefficienti sono accurati, non prudenti: servono a decidere, e una stima prudente porterebbe il motore a scartare abbinamenti validi. Il margine sugli orari comunicati al passeggero sta in una leva separata per operatore, tarabile sullo storico di esercizio: così una prudenza voluta nella promessa non peggiora la qualità delle decisioni.
Per ognuna: il contesto, la decisione, le alternative valutate, le conseguenze. Le conseguenze sfavorevoli sono scritte accanto a quelle favorevoli.
Ogni valore ha accanto la procedura che lo riproduce e la data in cui è stato misurato.
| Cosa si misura | Risultato | Come si riproduce | Data |
|---|---|---|---|
| Stima del primo tratto | Errore mediano sul singolo tratto 17,5%, sottostime nella metà dei casi. Con i coefficienti precedenti, sulla stessa tabella: 21,8% e 74%. | Stima applicata a 8.292 coppie fra 186 fermate reali e confrontata con il tempo del motore stradale, profilo del minibus. Campione a seme fisso. | 24 settembre 2026 |
| Profilo del minibus | Scarto medio per coppia sceso dal 20,6% al 10,1% sulle 101 coppie in cui i due sistemi percorrono le stesse strade. Somma dei tempi coincidente. | 120 coppie di fermate a campione, confrontate con i tempi di Google Maps. | 16 settembre 2026 |
| Completezza della tabella | 239.610 tratte su 490 fermate: nessuna coppia mancante. | Conteggio delle tratte per fermata di origine. | 17 settembre 2026 |
| Tenuta della ri-ottimizzazione | 236 minuti di domanda pari al doppio della capacità: ciclo al massimo di 44,7 secondi, mai oltre il minuto. Un'ora a quattro volte la capacità: massimo 25,9 secondi. | Simulazione sul motore vero, dentro una transazione annullata alla fine. | 7 agosto 2026 |
| Coerenza fra motore e simulazione | Differenza zero su ogni indicatore, a parità di domanda. | Autodiagnosi del motore, capitolo 10. | 6 agosto 2026 |