Come trovare una superstar in tempo lineare?


28

Prendi in considerazione i grafici diretti. Chiamiamo un nodo superstar se e solo se nessun altro nodo può essere raggiunto da esso, ma tutti gli altri nodi hanno un bordo a . formalmente:v v

v superstar :⟺outdeg(v)=0indeg(v)=n1

con il numero di nodi nel grafico. Ad esempio, nel grafico seguente, il nodo non compilato è una superstar (e gli altri nodi non lo sono).n

Una superstar
[ fonte ]

Come puoi identificare tutte le superstar in un grafico diretto in time? Una rappresentazione grafica adatta può essere scelta dai soliti candidati ; astenersi dall'utilizzare rappresentazioni che spostano la complessità del problema alla preelaborazione.O(n)

Non è possibile formulare ipotesi sulla densità. Non assumiamo che il grafico contenga una superstar; se non ce n'è, l'algoritmo dovrebbe riconoscerlo.

Notazione : è il numero di bordi in uscita di un nodo, simile per i bordi in arrivo.outdegindeg


1
È consentito dove sono i bordi o dobbiamo guardare solo i bordi su ciascun vertice? O(n+k)kO(1)
Kevin,

@Kevin No, è un requisito rigoroso. Per quanto riguarda la seconda domanda: non so nemmeno se sia necessario, ma di certo non puoi fare di più. O(n)
Raffaello

Conosci la risposta? Può essere fatto in ? O(n)
Dave Clarke,

@DaveClarke: Sì e sì.
Raffaello

È necessario limitare ulteriormente la rappresentazione; un algoritmo lineare è impossibile per un elenco di adiacenza (solo per confermare che un vertice è una superstar, potrebbe essere necessario scorrere l'intero elenco in ciascun vertice).
Gilles 'SO- smetti di essere malvagio'

Risposte:


18

Possiamo eliminare tutti i vertici tranne uno verificando l'esistenza di spigoli perché possiamo eliminare una possibilità per ogni spigolo che controlliamo. In particolare, se c'è un bordo che va da x a y , eliminiamo x e passiamo a y (poiché da esso è possibile raggiungere un altro vertice); in caso contrario, eliminiamo y (poiché non può essere raggiunto da x ). Una volta raggiunto l'ultimo vertice, qualsiasi vertice non eliminato dovrebbe essere confrontato con l'altro vertice (assicurarsi che la condizione superstar sia rispettata: c'è un vantaggio in arrivo ma non in uscita) fino a quando non viene eliminato o confermato come superstar. Alcuni pseudocodici:n1xyxyyx

vertex superstar(graph g)
    current vertex = first
    # Go through each vertex
    for each subsequent vertex in g ("next")
        # If there's an edge from this to the next, we eliminate this one [move to the new one].
        # If not, we just stay here.
        if edge exists from current to next
            candidate = next
        end if
    end for
    # Now we are on the final remaining candidate, check whether it satisfies the requirements.
    # just a rename for clarity
    candidate = current
    for each other vertex in g
        if edge from current to other exists
            return null 
        else if no edge from other to current
            return null
        end if
    end for
    return candidate
end superstar

Vediamo un esempio per illustrare il metodo. Prendi questo array, con il vertice di origine in alto e la destinazione a lato. 1 indica un bordo:

12341101210131114110

Grigherò i vertici che abbiamo escluso come potenziali superstar. Userò il verde e il rosso per indicare i bordi che stiamo osservando quando lo fanno e non contengono il bordo che stiamo cercando, e il blu per indicare dove abbiamo già guardato.

Iniziamo osservando i vertici 1 e 2.

Il numero verde indica che c'è un bordo da 2 a 1, quindi eliminiamo 2 e cerchiamo un bordo da 3 a 1 :

12341101210131114110

12341101210131114110-

Vediamo che non esiste tale vantaggio, quindi eliminiamo 1 e prendiamo 3 come vertice corrente. Ricordiamo che ne abbiamo già eliminati 2, quindi vedi se c'è un vantaggio da 4 a 3:

12341101210131114110

C'è un bordo da 4 a 3, quindi eliminiamo 4. A questo punto abbiamo eliminato tutti i vertici tranne uno (3), quindi controlla i suoi bordi e vedi se si qualifica:

12341101210131114110

C'è un vantaggio da 1 a 3 ma non il contrario, quindi 3 è ancora un candidato.

12341101210131114110

C'è anche un vantaggio da 2 a 3 ma non il contrario, quindi 3 è ancora un candidato.

12341101210131114110

C'è un vantaggio da 4 a 3 ma non da 3 a 4; che completa il nostro controllo dei bordi di 3 e abbiamo scoperto che è, in effetti, una superstar.

n1nnn12×(n1)3n3O(n)Θ(n)


8

Non è questo il problema delle celebrità ?

Ci sarà una sola superstar (celebrità) se ce n'è una.

A[i,j]=1ij0

A[i,j]O(1)A[i,j]=1iA[i,j]=0j

Mantenere un elenco di candidati attuali, eliminando uno per uno. Un elenco collegato dovrebbe essere sufficiente.

Alla fine, puoi verificare se il tuo candidato è davvero una superstar.

O(n)


(io,j)

3
@Raphael: scegli i primi due candidati dalla lista collegata. (testa e testa-> successiva).
Aryabhata,

6

Questa risposta si rivolge alla versione della domanda in cui era possibile qualsiasi rappresentazione grafica, non alla versione corrente della domanda.

  • Memorizza il tuo grafico come coppia di elenchi di adiacenza e di elenchi di adiacenza inversa, in cui ogni elenco contiene inoltre la lunghezza dell'elenco, quindi il numero out e in-edge, rispettivamente.

  • O(|E|)

  • 0n-1O(|N|)


Ok, vedo che consentire qualsiasi rappresentazione grafica è troppo debole. Ho limitato la domanda a ciò che intendevo.
Raffaello

2

Solo per riferimento, questo è lo pseudocodice di una versione ricorsiva di ciò che Kevin ha pubblicato.

superstar(V, E) {
  if ( |V| == 1 ) {
    return V.pop
  }

  a = V.pop
  b = V.pop
  if ( (a,b) ∈ E ) {
    no_ss = a
    keep  = b
  }
  else {
    no_ss = b
    keep = a
  }

  s = superstar(V ++ keep)

  return ( s != null && (no_ss, s) ∈ E && !(s, no_ss) ∈ E ) ? s : null
}

hasSuperstar(V, E) = superstar(V, E) != null
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.