Come abbiamo già detto in un instradamento link-state la topologia di rete e tutti i costi dei collegamenti sono noti, ossia disponibili in input all'algoritmo. Ciò si ottiene facendo inviare a ciascun nodo, pacchetti sullo stato dei suoi collegamenti a tutti gli altri nodi della rete. Questi
pacchetti contengono identità e costi dei collegamenti connessi al nodo che li invia.
In pratica, questo risultato si ottiene (come per esempio nel protocollo OSPF) tramite un algoritmo di link-state broadcast.
L’algoritmo di calcolo dei percorsi che presentiamo associato all’instradamento
link-state è noto come algoritmo di Dijkstra, dal nome del suo ideatore. Un algoritmo
strettamente collegato è quello di Prim.

Algoritmo di Dijkstra
...

Dijkstra calcola il percorso a costo minimo da un nodo (l'origine, che chiameremo ) a tutti gli altri nodi della rete. L'algoritmo è iterativo e ha le seguenti proprietà: dopo la -esima iterazione, i percorsi a costo minimo sono noti verso nodi di destinazione e, tra i percorsi a costo minimo verso tutti i nodi di destinazione, questi percorsi hanno i costi più bassi. Vediamo di capire bene cosa vuol dire questa affermazione: avendo un certo di nodi nel grafo e data un origine , dopo un certo numero di iterazioni dell'algoritmo di Dijkstra, diciamo , saranno stati trovati percorsi minimi da verso nodi di destinazione, se nelle iterazioni precedenti fossero stati trovati altri percorsi da verso questi nodi, dopo iterazioni siamo sicuri che quelli minimi attualmente trovati sono effettivamente minimi entro la -esima iterazione.
Adotteremo la seguente notazione:

  • : costo minimo del percorso dal nodo origine alla destinazione per quanto concerne l'iterazione corrente dell'algoritmo.
  • : immediato predecessore di lungo il percorso a costo minimo dall'origine a .
  • : sottoinsieme di nodi contenente tutti (e solo) i nodi per cui il percorso a costo minimo dall'origine a è definitivamente noto.

L'algoritmo di instradamento centralizzato consiste in un passo di inizializzazione seguito da un ciclo che viene eseguito una volta per ogni nodo del grafo. Quando termina, l'algoritmo avrà calcolato il percorso minimo dal nodo origine a tutti gli altri nodi.

Algoritmo di Dijkstra
...
Inizializzazione:
 N' = {u}
 per tutti i nodi v
	se v è adiacente a u
		allora D(v) = c(u,v)
	altrimenti D(v) = infinito

Ciclo
 determina un w non in N' tale che D(w) sia minimo
 aggiungi w a N'
 aggiorna D(v) per ciascun nodo v adiacente a w e non in N'
		  D(v) = min(D(v), D(w) + c(w,v))
 /* il nuovo costo verso v è il vecchio costo verso v oppure il costo del costo del
    del percorso minimo noto verso w più il costo da w a v */
 ripeti il ciclo fino a che non si verifica N' = N

Pasted image 20231014115414.png
Esecuzione dell'algoritmo sulla rete della figura sopra: diciamo di voler conoscere tutti percorsi che vanno dal router al router .
inizialmente contiene solo .

Per tutti i nodi che sono adiacenti (vicini) a allora segniamo la distanza nota tra e i nodi vicini. In questo caso i vicini sono , e , rispettivamente con i costi , e . I costi verso e sono posti all'infinito .
Nella prima iterazione prendiamo in considerazione i nodi non ancora aggiunti all'insieme e determiniamo il nodo a costo minimo che è , aggiungiamo a .
Considereremo una tabella come quella che segue, in cui abbiamo il passo dell'algoritmo e le distanze note da tutti i nodi e in cui indichiamo anche il predecessore immediato al nodo specificato nella colonna corrente.

Passo
0

Una volta appurato che è il nodo più vicino a , lo aggiungiamo a e aggiorniamo le distanze.
Infatti da si possono raggiungere tre nodi:

  • con distanza
  • con distanza
  • con distanza
    A questo punto dobbiamo confrontare il peso del percorso di cui è già nota la distanza con il peso del percorso se fosse raggiunto da .
    La distanza da attualmente segnata è , da è , in questo caso il percorso per raggiungere passando da non è conveniente, allora lo si lascia com'è.
    La distanza da attualmente segnata è , da è , , in questo caso il percorso per raggiungere passando da è più conveniente allora va aggiornato.
    La distanza da attualmente segnata è , da è che è sicuramente minore di infinito, per cui anche questo va aggiornato.
Passo
0
1

A questo punto va scelto il percorso minimo, tra quelli attualmente noti.
Teniamo presente che è stato ispezionato e che non è da considerare tra le scelte.
Due percorsi minimi hanno lo stesso valore e sono i percorsi verso e verso entrambi con peso .
Possiamo sceglierne uno a caso tra i due, diciamo e lo aggiungiamo a .
è collegato a due nodi:

  • con distanza
  • con distanza
    La distanza attualmente nota per è , da sarebbe che risulta essere inferiore a , va aggiornato.
    La distanza attualmente nota per è da sarebbe che risulta essere inferiore a infinito, va aggiornato.
Passo
0
1
2

L'algoritmo continua così fino a che non si ottiene che .
L'algoritmo finito mostra la seguente tabella:
Pasted image 20231016100559.png
quando Dijkstra finisce, abbiamo per ciascun nodo il suo predecessore lungo il percorso a costo minimo dal nodo origine. Per ciascun predecessore abbiamo il rispettivo predecessore, e in questo modo riusciamo a costruire l'interno percorso dall'origine a tutte le destinazioni. La tabella di inoltro di un nodo, diciamo , può essere ricostruita da queste informazioni memorizzando, per ciascuna destinazione, il nodo del successivo hop sul percorso a costo minimo da alla destinazione.
Pasted image 20231016100914.png
La figura sopra mostra i percorsi a costo minimo risultati dal grafo fornito inizialmente.
La complessità di Dijkstra è .
Un'implementazione dell'algoritmo che sfrutta la struttura dati heap riesce a determinare il minimo della riga 9 (determina un w non in N' tale che w sia minimo) in tempo logaritmico anziché lineare riducendone la complessità totale.

Oscillazioni di Dijkstra

Prima di concludere con Dijkstra, diamo un'occhiata ad una situazione che si può verificare.
Diciamo di avere la seguente topologia di rete:
Pasted image 20231016102410.png
in cui abbiamo i router e che producono una unità di traffico diretta verso e che produce traffico pari a diretto a . In questa topologia di rete i costi dei collegamenti sono pari al traffico trasportato sul collegamento. Inoltre il traffico sui collegamenti non è simmetrico, ovvero il costo è uguale al costo se e solo se il carico trasportato in entrambe le direzioni del collegamento è lo stesso.
In questa fase inziale, le tabelle di inoltro sono impostate in modo da instradare il traffico come è illustrato in figura (a).
Nella successiva iterazione dell'algoritmo, il nodo determina, sulla base dei costi dei collegamenti indicati nella figura a, che il percorso in senso orario verso ha costo 1, mentre il percorso in senso antiorario ha costo . Pertanto il percorso a costo minimo di verso ora è quello in senso orario. Analogamente, determina che il proprio nuovo percorso a costo minimo verso è quello in senso orario, il che porta ai risultati in figura b.
Pasted image 20231016103844.png
Quando l'algoritmo viene eseguito nuovamente e instradano tutti il proprio traffico su percorsi in senso anti orario:
Pasted image 20231016104043.png
La volta successiva tutti i nodi e instradano il loro traffico in senso orario.
Pasted image 20231016104124.png
Che cosa si può fare per evitare tali oscillazioni (di cui soffrono tutti gli algoritmi che utilizzano una metrica dei collegamenti basata sulla congestione o sul ritardo)? Una soluzione consiste nello stabilire che i costi dei collegamenti non dipendono dalla quantità di traffico trasportato: ipotesi inaccettabile dato che uno scopo dell'instradamento è evitare collegamenti troppo intasati. Un'altra soluzione consiste nell'assicurarsi che non tutti i router lancino l'esecuzione dell'algoritmo nello stesso istante.