Lascia che la parte successiva di un grafico:
Quando uso la funzione shortest_path tra i punti A e B, ho il percorso blu. Perché succede?
Lascia che la parte successiva di un grafico:
Quando uso la funzione shortest_path tra i punti A e B, ho il percorso blu. Perché succede?
Risposte:
Ecco come si comporta shortest_path (l'algoritmo di Dijkstra) in pgRouting. Se ci sono due fronti con la stessa sorgente e destinazione, viene usato uno casuale (per essere precisi: il primo, che viene fuori dal database). Non conosco alcuna soluzione per questo, ma ci sono alcune soluzioni alternative.
Se possibile, dovresti dividere uno di quei bordi in due. Non l'ho provato, ma dovrebbe risolvere quel comportamento.
Altra soluzione per caso, quando non è possibile modificare il set di dati. Aggiungi il campo 'shorter_alternative' al tuo tavolo. Query di esempio, modificala in base alle tue esigenze. Spero che spieghi l'idea:
UPDATE roads t1
SET shorter_alternative = t2.id
FROM roads t2
WHERE
((t2.source = t1.source AND t2.target = t1.target) OR
(t2.source = t1.target AND t2.target = t1.source)) AND
(t2.length < t1.length)
Ora, il bordo '0.098' conterrà l'id del bordo '0.011'. Tutti gli altri bordi avranno null nel campo shorter_alternative. Dopo aver effettuato la query shortest_path, controllare il set di dati restituito: se per qualsiasi riga è impostato un campo shorter_alternative, modificarlo.
Il problema è già stato descritto nella risposta precedente. È un problema degli algoritmi del percorso più breve "basati su vertici", che si preoccupano solo di sorgente e target.
C'è un ticket nel tracker dei problemi e una possibile soluzione per modificare l'implementazione dell'algoritmo: https://github.com/pgRouting/pgrouting/issues/34 (Sarebbe bello se qualcuno potesse provare questo e inviare una richiesta pull; - )
Un'altra possibilità è quella di dividere i "collegamenti stradali paralleli" come menzionato prima. Oppure potresti usare l'algoritmo Shooting Star, che si dirige da un lato all'altro in modo da "conoscere" entrambi i collegamenti stradali.
Oppure puoi provare a ordinare la rete stradale in base al costo e quindi selezionare solo combinazioni distinte di origine e destinazione:
SELECT * FROM shortest_path(
'SELECT DISTINCT ON (source, target)
gid as id,
source::integer,
target::integer,
cost::double precision
FROM ways ORDER BY source, target, cost',
true,false
);
Ciò presuppone che cerchi il percorso meno costoso. Altrimenti devi farlo ORDER BY ... DESC
.
Devi provare se questo influisce sulle prestazioni.
In realtà ho creato una patch per pgRouting, che risolve il problema: https://github.com/pgRouting/pgrouting/issues/78