Quale algoritmo di attraversamento grafico dovrei usare?

0

Vorrei scrivere un algoritmo in grado di attraversare un grafico e, auspicabilmente, in seguito, posso implementarlo per un sistema di navigazione interno. Il grafico proviene da piante di un edificio e i nodi grafici rappresentano gli oggetti dell'edificio come porte, corridoi, scale, stanze, ecc.

Il sistema di navigazione accetterà utenti diversi con capacità diverse, queste funzionalità sono memorizzate nel profilo utente. Per ogni singolo utente (o un gruppo di utenti dello stesso tipo, ad esempio un membro dello staff), il sistema restituisce un percorso specifico per quell'utente / i considerando la sua funzionalità personale. Ad esempio, se l'utente del sistema sta utilizzando una sedia a rotelle, il sistema dovrebbe escludere tutti i nodi delle scale dal percorso (saranno contrassegnati come non attraversabili). Allo stesso modo se per entrare in uno spazio interno, l'utente deve avere una chiave o essere un membro dello staff, ma NON lo è, il sistema dovrebbe contrassegnare il nodo (es. La porta che richiede la chiave) non-traversabile e dovrebbe cercare quei percorsi che non richiedono questi requisiti specifici.

Questa è stata la prima parte e qui utilizzo una funzione per verificare queste condizioni per un determinato utente. Gli input per questa funzione sono un nodo e un utente. Se le condizioni richieste dal nodo NON sono soddisfatte (significa che il profilo utente non corrisponde alla condizione richiesta dal nodo) la funzione restituisce false = non-traversable.  Se la condizione è vera, il nodo rimane inversibile e verrà memorizzato da qualche parte e verrà preso in considerazione per il calcolo del percorso finale.

La seconda parte è che ho una lista che contiene tutti i nodi che sono attraversabili e ora il percorso più breve sarà calcolato sulla base di 3 diversi costi, energia, tempo e denaro. Il costo finale può essere una combinazione di questi costi e imposta i pesi per i bordi.

Il mio problema riguarda la prima parte. Voglio sapere come posso creare un algoritmo che produce il sottografo (la lista con i nodi percorribili in esso). E in seguito come posso usare questo algoritmo per modificare Dijkstra per adattarlo a questo sistema.

Qualcuno può aiutare con la scrittura di uno pseudocodice per l'algoritmo in modo che io possa capire come funzionerebbe in passi chiari o qualche suggerimento su come posso fare questi passaggi in pseudocodice?

Tieni presente che in questa fase le prestazioni non sono molto importanti per me.

    
posta NKK 08.01.2014 - 19:25
fonte

2 risposte

2

Il solito modo di risolvere quello sarebbe invece di fare un passo di pre-elaborazione prima di eseguire Dijkstra, basta eseguire Dijkstra e dare a tutti i bordi non traversabili un peso davvero elevato. In questo modo eviti di preelaborare nodi che non sono assolutamente nel percorso più breve e inoltre eviti il problema di non trovare un percorso che potrebbe essere effettivamente più breve, ma che viene dopo quando cerchi l'ordine dei bambini.

Potresti anche considerare A * se i tuoi pesi sono distanze. È più efficiente nell'eliminare i nodi che non ti servono.

    
risposta data 08.01.2014 - 21:21
fonte
0

Con tutto il dovuto rispetto, trovo la maggior parte delle risposte e dei commenti fino ad ora un po 'di confusione, e non c'è ancora una risposta diretta. Per esempio non ha senso parlare di euristica (quindi di algoritmo A *) dato che noi non abbiamo alcuna informazione che aiuti a guidare la ricerca, e inoltre il problema, come affermato chiaramente, è non ricerca o prestazioni, ma la questione del nodo traversabilità

Inoltre, il trucco di impostare un costo elevato per i nodi non interscambiabili funziona in una certa misura, ma ... Il problema è che quei nodi rimarranno ancora nel grafico e saranno ricercati come qualsiasi altro, il che influenzerà le prestazioni più tardi. L'altro problema è che il costo di un nodo alto non sarà di aiuto se non esiste un altro percorso di soluzione; in tal caso si può trovare un percorso che attraversa un nodo non traversabile (che sarebbe chiaramente un "bug" importante con il programma!) Quindi per entrambi i motivi è necessario rimuovere nodi non traversabili.

Ora, dato il problema come detto, e poiché l'autore conosce l'algoritmo Dijkstra (che è comunque il più appropriato per lo scenario dato), si tratta semplicemente di modificare la parte dell'algoritmo che genera i figli di un nodo e li inserisce nella coda. Cioè, invece di accodarli tutti, incondizionatamente, possiamo usare la funzione isTraversable specifica per utente per determinare quale accodare e quale scartare.

Di seguito alcuni pseudocodici (ampiamente adattati da cprogramming.com ), con il test aggiuntivo di cui hai bisogno in maiuscolo:

/* Given graph G, with edges E of the form (v1, v2) and vertices V, and a source vertex s
* 
*  dist : array of distances from the source to each vertex
*  prev : array of pointers to preceding vertices
*  i    : loop index
*  U    : list or heap of vertices
*/

/* Initialization: set every distance to INFINITY until we discover a path */
for i = 0 to |V| - 1
    dist[i] = INFINITY
    prev[i] = NULL
dist[s] = 0    /* The distance from the source to itself is zero */

/* Examine the many alternative paths, always picking "the vertex, v, with the
 * shortest path to s" first, to guarantee finding the optimal solution */

while (U is not empty)
   pick the vertex, u, in U with the shortest path to s
   if u is the goal
        return u
   if dist[u] is INFINITY
       return error: no solution
   remove u from U
   for each child node v of u  /* edge (u, v) */
        if v is in U
            IF v IS_TRAVERSABLE
                if(dist[u] + length(u, v) < dist[v])
                    dist[v] = dist[u] + length(u, v)
                    prev[v] = u
            ELSE
                remove v from u
    
risposta data 01.04.2014 - 22:14
fonte

Leggi altre domande sui tag