Qual è l'algoritmo e la struttura dati più efficienti per mantenere le informazioni dei componenti collegati su un grafico dinamico?


9

Supponiamo che io abbia un grafico sparso finito non indirizzato e che debba essere in grado di eseguire in modo efficiente le seguenti query:

  • IsConnected(N1,N2) - restituisce se esiste un percorso tra e , altrimentiN 1 N 2 FTN1N2F
  • ConnectedNodes(N) : restituisce il set di nodi che sono raggiungibili daN

Questo è facilmente eseguibile pre-calcolando i componenti collegati del grafico. Entrambe le query possono essere eseguite in .O(1)

Se devo anche essere in grado di aggiungere arbitrariamente i bordi - - allora posso memorizzare i componenti in una struttura di dati disgiunta . Ogni volta che viene aggiunto un bordo, se collega due nodi in componenti diversi, unirei quei componenti. Ciò aggiunge il costo a e a e (che potrebbe anche essere O (1) ).AddEdge(N1,N2)A d d E d g e O ( I n v e r s e A c k e r m a n n ( | N o d e s | ) ) I s C o n n e c t e d C o n n e c t e d N oO(1)AddEdgeO(InverseAckermann(|Nodes|))IsConnectedO ( 1 )ConnectedNodesO(1)

Se devo anche essere in grado di rimuovere arbitrariamente i bordi, qual è la migliore struttura di dati per gestire questa situazione? Uno è noto? Riassumendo, dovrebbe supportare in modo efficiente le seguenti operazioni:

  • T N 1 N 2 FIsConnected(N1,N2) - restituisce se esiste un percorso tra e , altrimenti .TN1N2F
  • NConnectedNodes(N) - restituisce l'insieme dei nodi che sono raggiungibili da .N
  • AddEdge(N1,N2) : aggiunge un bordo tra due nodi. Nota che , o entrambi potrebbero non esistere prima.N 2N1N2
  • RemoveEdge(N1,N2) : rimuove un bordo esistente tra due nodi.

(Sono interessato a questo dal punto di vista dello sviluppo del gioco - questo problema sembra verificarsi in parecchie situazioni. Forse il giocatore può costruire linee elettriche e dobbiamo sapere se un generatore è collegato a un edificio. Forse il giocatore può bloccare e sbloccare le porte, e dobbiamo sapere se un nemico può raggiungere il giocatore. Ma è un problema molto generale, quindi l'ho definito come tale)


ConnectedNodes non potrebbe essere eseguito in , perché se restituisce un elenco di nodi, avrebbe bisogno di tempo. L'implementazione di con un BFS è ottimale, quindi una potenziale struttura di dati dovrebbe supportare solo IsConnected, AddEdge e RemoveEdge. Questo sembra rilevante per la tua domanda: stackoverflow.com/questions/7241151/…n Ω ( n ) C o n n e c t e d N o d e sO(1)nΩ(n)ConnectedNodes
Tom van der Zanden,

@TomvanderZanden Restituire un set già costruito (in programmazione, un puntatore o un riferimento) è ... anche se non c'è molto che l'utente di possa fare quel e non coperto da . O(1)ConnectedNodesO(1)IsConnected
user253751

Risposte:


11

Questo problema è noto come connettività dinamica ed è un'area attiva di ricerca nella comunità teorica dell'informatica. Ancora alcuni problemi importanti sono ancora aperti qui.

Per chiarire la terminologia, si richiede una connettività completamente dinamica poiché si desidera aggiungere ed eliminare i bordi. C'è un risultato di Holm, de Lichtenberg e Thorup (J.ACM 2001) che raggiunge il tempo di aggiornamento e il tempo di query . Dalla mia comprensione sembra essere implementabile. In parole semplici, la struttura dei dati mantiene una gerarchia di spanning tree e la connettività dinamica negli alberi è più semplice da coprire. Posso consigliare le note di Erik D. Demaine per una buona spiegazione, vedi qui per un video. La nota di Erik contiene anche puntatori ad altri risultati rilevanti. Come nota: tutti questi risultati sono risultati teorici.O(log2n)O(logn/loglogn)

Queste strutture di dati potrebbero non fornire query ConnectedNodes di per sé, ma è facile ottenerlo. Mantenete semplicemente come struttura di dati aggiuntiva il grafico (diciamo come lista dei bordi doppiamente connessa) e fate la ricerca approfondita per ottenere i nodi che possono essere raggiunti da un certo nodo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.