Iterative deepening A*

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazione Vai alla ricerca
Iterative deepening A*
ClasseAlgoritmo di ricerca
Struttura datiGrafo
Caso peggiore temporalmente[1]
Caso peggiore spazialmente
Ottimale
Completo

Iterative deepening A* (noto anche con l'acronimo IDA*) è un algoritmo euristico proposto da Richard Korf nel 1985. È in grado di trovare il cammino minimo fra un nodo indicato come iniziale e ciascun membro di un insieme di "nodi soluzione" in un grafo pesato.

L'algoritmo è una variante dell'iterative deepening depth-first search usata per migliorare le prestazioni di A*.[2] Il vantaggio principale di IDA* è infatti l'uso lineare della memoria, al contrario di A* che ha bisogno, nel caso peggiore, di uno spazio esponenziale. D'altro canto, questo algoritmo usa fin troppa poca memoria, che potrebbe essere invece sfruttata per migliorare le prestazioni in termini di tempo (cfr. memoizzazione).[3]

Descrizione[modifica | modifica wikitesto]

Esattamente come nell'iterative deepening depth-first search, l'algoritmo viene ripetuto più volte con una soglia sempre più grande, finché non verrà raggiunta una soluzione. Tuttavia, in questo caso la soglia non dipenderà più dalla profondità rispetto al nodo radice, ma dal valore assunto dalla funzione di valutazione. Come in A* ed altri algoritmi euristici, viene usata come funzione di valutazione , dove è il costo accumulato per raggiungere il nodo , mentre è una stima euristica del costo necessario per arrivare alla soluzione partendo da .

L'algoritmo inizia impostando la soglia (threshold) dove è il nodo iniziale, e mette i figli di in una coda (detta fringe). Successivamente, espande i nodi nel fringe per i quali , finché non raggiunge una soluzione. Se nel fringe non è presente nessun tale che , allora l'algoritmo imposta , ovvero aggiorna la soglia in base al minimo valore assunto dalla funzione di valutazione fra tutti i nodi del fringe.[4]

A causa del numero di volte che l'algoritmo può espandere lo stesso nodo, la sua esecuzione rimane, nel peggiore dei casi, esponenziale in termini di tempo. Questo problema è in parte attenuato in altri algoritmi, quali RBFS e le varie implementazioni di MA*.[2]

Implementazione[modifica | modifica wikitesto]

 path              percorso di ricerca attuale (si comporta come una pila)
 node              nodo attuale (ultimo nodo di path)
 g                 il costo per raggiungere il nodo corrente
 f                 costo stimato per raggiungere la soluzione (radice->nodo attuale->soluzione)
 h(node)           costo stimato per raggiungere la soluzione (nodo attuale->soluzione)
 cost(node, succ)  costo per il prossimo passo
 is_goal(node)     funzione booleana che assume valore di verità se il nodo è una soluzione
 successors(node)  funzione di espansione di un nodo, sceglie i successori ordinandoli in base a g + h(n)
 ida_star(root)    restituisce o NOT_FOUND o una coppia di valori (cammino, costo)
   
 procedure ida_star(root)
   bound := h(root)
   path := [root]
   loop
     t := search(path, 0, bound)
     if t = FOUND then return (path, bound)
     if t = ∞ then return NOT_FOUND
     bound := t
   end loop
 end procedure

 function search(path, g, bound)
   node := path.last
   f := g + h(node)
   if f > bound then return f
   if is_goal(node) then return FOUND
   min := ∞
   for succ in successors(node) do
     if succ not in path then
       path.push(succ)
       t := search(path, g + cost(node, succ), bound)
       if t = FOUND then return FOUND
       if t < min then min := t
       path.pop()
     end if
   end for
   return min
 end function

Proprietà[modifica | modifica wikitesto]

Come per A*, IDA* garantisce una soluzione ottimale per il problema del cammino minimo quando la funzione euristica è ammissibile,[4] ovvero tale che

per tutti i nodi del grafo, dove è il costo effettivo per raggiungere la soluzione a partire dal nodo .

IDA* è particolarmente utile quando si opera in un sistema con memoria limitata. La ricerca A* mantiene una gran quantità di nodi inesplorati in memoria, che si riempie esponenzialmente. Di contro, dato che IDA* non mantiene in memoria alcun nodo tranne quelli del cammino corrente, richiede una quantità di memoria lineare rispetto alla lunghezza della soluzione cercata. La sua complessità in termini di tempo è stata analizzata da Korf et al. sotto l'assunzione che l'euristica sia consistente (condizione più forte rispetto all'euristica ammissibile), ovvero tale che

per ogni nodo e per ogni suo successore ; conclusero che, se messo a confronto con algoritmi di ricerca non informati (ovvero a forza bruta), i quali trovano una soluzione in tempi esponenziali, IDA* riduce la profondità di ricerca della soluzione (di un fattore costante), ma non riduce il fattore di diramazione.[5]

Note[modifica | modifica wikitesto]

  1. ^ Dove è il fattore di diramazione (branching factor) e è la profondità della soluzione.
  2. ^ a b Russell & Norvig, 2009, p. 99.
  3. ^ Russell & Norvig, 2009, p. 101.
  4. ^ a b Korf, 1985, p. 7.
  5. ^ Korf et al., 2001.

Bibliografia[modifica | modifica wikitesto]

Voci correlate[modifica | modifica wikitesto]

  Portale Informatica: accedi alle voci di Wikipedia che trattano di informatica