Salta al contenuto
Note per Studenti Esercizio 22 · vertici influenzabili e vertici entro distanza d

Esercizio 22vertici influenzabili e vertici entro distanza d

Esame
In questa pagina 3

Testo.

Parte A (esempio di tema d'esame, seconda parte, esercizio 2, 6 punti). Sia G=(V,E)G = (V, E) un grafo che rappresenta una rete sociale con nn vertici ed mm archi. Ogni vertice u∈Vu \in V ha un campo LV[u]L_V[u].influencer che vale 11 se uu è un influencer e 00 altrimenti. Un vertice xx non influencer si dice influenzabile se esiste un influencer yy e un cammino tra xx e yy. Progettare in pseudocodice un algoritmo Influenzabili che conti il numero di vertici influenzabili in GG, e analizzarne la complessità. Per avere punteggio pieno la complessità deve essere O(n+m)O(n + m).

Parte B (scritto del 09/07/2024, seconda parte, esercizio 2, 7 punti; una variante compare in un esempio di tema d'esame). Un grafo G=(V,E)G = (V, E) non orientato, semplice, non necessariamente connesso, rappresenta gli utenti di un social network: ogni vertice è un utente e ogni arco una relazione di amicizia reciproca. Due utenti amici sono a grado di amicizia 11; gli amici di uno dei due che non sono amici dell'altro hanno grado di amicizia 22 rispetto a quest'ultimo, e così via. Scrivere un algoritmo che, preso in input il grafo GG rappresentato tramite liste di adiacenza, un qualsiasi utente s∈Vs \in V e un intero dd, restituisca il numero degli utenti di VV che si trovano rispetto a ss a un grado di amicizia ≤d\le d. (La variante dell'esempio di tema chiede, per ogni v∈Vv \in V, di salvare in v.numNeighbors il numero di nodi a distanza ≤k\le k da vv.) (a) Descrivere l'idea con un esempio. (b) Pseudocodice, specificando input e output. (c) Analizzare la complessità.


Parte A: vertici influenzabili

Idea

xx è influenzabile se sta nella stessa componente connessa di un influencer. Si lancia una visita (BFS o DFS, vedi Visite di grafi - BFS e DFSVisite in ampiezza (BFS) e in profondità (DFS) come design pattern; etichette discovery, cross e back edge; BFS tree e distanze; complessità Theta(n+m) con liste di adiacenza; applicazioni (connettività, componenti, spanning tree, cammini minimi non pesati, cicli, vertici a distanza al più d); esempio svolto su un grafo di 7 vertici.Visite di grafi - BFS e DFS →) da ogni influencer non ancora visitato: ogni vertice raggiunto è nella componente di un influencer. Al termine si contano i vertici visitati che non sono influencer.

Altra scelta: ogni influencer è una sorgente di una BFS; se un influencer è già visitato (perché nella componente di un altro) non serve ripartire, e la visita non riparte mai su vertici già visitati: ogni vertice è esaminato una sola volta.

Pseudocodice

Algoritmo Influenzabili(G)
Input: grafo G=(V,E) con liste di adiacenza; campo influencer di ogni vertice
Output: numero di vertici non influencer che stanno nella componente connessa di un influencer
forall v in V do v.ID <- 0
conta <- 0
forall v in V do
    if v.influencer = 1 AND v.ID = 0 then
        BFS(G, v)                       (visita tutta la componente di v ponendo ID <- 1)
forall v in V do
    if v.ID = 1 AND v.influencer = 0 then conta <- conta + 1
return conta

(In alternativa si conta durante la visita: ogni volta che si inserisce in lista un vertice ww con influencer = 0 si incrementa conta.)

Complessità

Ogni vertice viene scoperto al più una volta in tutte le chiamate (dopo la prima visita ha ID ≠0\ne 0) e ogni arco viene esaminato al più due volte (una per estremo), quindi le BFS costano in totale O(n+m)O(n + m). I due cicli sui vertici costano Θ(n)\Theta(n). Totale Θ(n+m)\Theta(n + m) con le liste di adiacenza.

Esempio. Vertici 1,…,61, \dots, 6, archi 12,23,4512, 23, 45 (il vertice 66 è isolato), influencer: 11 e 66. La BFS da 11 visita {1,2,3}\{1, 2, 3\}; 66 è un influencer non visitato: la BFS visita solo {6}\{6\}. Non influencer visitati: 22 e 33 ⇒\Rightarrow 22 influenzabili (44 e 55 stanno in una componente senza influencer). (Confronto con il calcolo delle componenti su 500 grafi casuali: risultati uguali.)

Parte B: vertici a distanza al più dd

Idea

La BFS da ss visita i vertici per livelli LiL_i secondo la distanza ii da ss (vedi Visite di grafi - BFS e DFSVisite in ampiezza (BFS) e in profondità (DFS) come design pattern; etichette discovery, cross e back edge; BFS tree e distanze; complessità Theta(n+m) con liste di adiacenza; applicazioni (connettività, componenti, spanning tree, cammini minimi non pesati, cicli, vertici a distanza al più d); esempio svolto su un grafo di 7 vertici.Visite di grafi - BFS e DFS →). Basta fermarsi al livello dd: i vertici dei livelli L0,…,LdL_0, \dots, L_d sono esattamente quelli a distanza ≤d\le d.

Esempio: cammino s−a−b−cs - a - b - c con un vertice xx adiacente ad aa e a cc. L0={s}L_0 = \{s\}, L1={a}L_1 = \{a\}, L2={b,x}L_2 = \{b, x\}, L3={c}L_3 = \{c\}. Per d=2d = 2 la risposta è 44 (s,a,b,xs, a, b, x); per d=1d = 1 è 22; per d=0d = 0 è 11 (solo ss).

Pseudocodice

Algoritmo contaEntro(G, s, d)
Input: grafo G (liste di adiacenza), vertice s, intero d >= 0; tutti gli ID valgono 0 e le label null
Output: numero di vertici a distanza <= d da s
s.ID <- 1; L0 <- lista con s; i <- 0; conta <- 1
while i < d AND Li non è vuota do
    Li+1 <- lista vuota
    forall v in Li do
        forall e in G.incidentEdges(v) do
            w <- G.opposite(v, e)
            if w.ID = 0 then
                w.ID <- 1; inserisci w in Li+1; conta <- conta + 1
    i <- i + 1
return conta

Qui non occorre etichettare gli archi: basta il controllo su ID dei vertici. Se serve il risultato per tutti i vertici vv (primo testo), si ripete per ciascuno, riportando gli ID a 00 ad ogni giro: Θ(n(n+m))\Theta(n(n + m)).

Complessità

Ogni vertice entra in una lista al più una volta e di ciascun vertice dei livelli L0,…,Ld−1L_0, \dots, L_{d-1} si scorre la lista di adiacenza: costo O(nd+md)O(n_d + m_d), dove ndn_d ed mdm_d sono vertici e archi coinvolti. Nel caso pessimo, O(n+m)O(n + m) per una sorgente. (Controllato con una implementazione confrontata con il calcolo di tutte le distanze su 300 grafi casuali.)

Errori comuni

  • Parte A: contare anche gli influencer, o contare i vertici di tutte le componenti (anche senza influencer).
  • Parte A: rilanciare la BFS da ogni influencer senza controllare ID: ogni componente verrebbe visitata più volte, ma si può ancora arrivare a O(n⋅(n+m))O(n \cdot (n + m)) se molti influencer stanno nella stessa componente.
  • Parte B: usare la DFS (non dà le distanze minime) o arrestare la BFS al livello d−1d - 1 o d+1d + 1.
  • Dimenticare che il grafo può essere sconnesso: la BFS visita solo la componente di ss e i vertici fuori restano a distanza ∞\infty.

Versione ripasso

Testo. (A) Rete sociale con campo influencer: contare i vertici non influencer che hanno un cammino verso un influencer, in O(n+m)O(n + m). (B) Dati GG, ss e dd: numero di vertici a distanza ≤d\le d da ss.

Teoria collegata