Ricerca nello spazio degli stati - formulazione dei problemi e ricerca non informata
In questa pagina 8
Un agente basato su obiettivi (Agenti intelligenti - ambienti, PEAS e tipi di agenteUn agente è una funzione dalle sequenze di percezioni alle azioni; è razionale se per ogni sequenza sceglie l'azione che massimizza il valore atteso della misura di prestazione, date le percezioni e la conoscenza incorporata. L'ambiente di lavoro si descrive con PEAS (Performance, Environment, Actuators, Sensors) e si classifica con sette coppie di proprietà (osservabile, deterministico, episodico, statico, discreto, singolo/multi-agente, noto). Le architetture crescono in complessità: reattivo semplice, reattivo basato su modello, basato su obiettivi, basato su utilità, più l'agente che apprende (elemento esecutivo, di apprendimento, critico, generatore di problemi).Agenti intelligenti - ambienti, PEAS e tipi di agente →) deve trovare da solo la sequenza di azioni che porta all'obiettivo. Questa nota mostra come si formula un problema e come lo si risolve cercando nello spazio degli stati con algoritmi che conoscono solo la definizione del problema (ricerca non informata). Gli algoritmi che usano una stima della distanza dall'obiettivo sono in Ricerca informata - greedy best-first, A* ed euristicheLa ricerca informata usa una funzione euristica h(n) che stima il costo da n all'obiettivo. Greedy best-first espande il nodo con h minima (f = h): veloce ma non ottima né in generale completa. A∗ usa f = g + h e, con h ammissibile (mai sopra il costo vero) e, sul grafo con tabella dei raggiunti, consistente, è completa e ottima; il fattore di diramazione effettivo b∗ misura la qualità di h, e un'euristica che ne domina un'altra espande meno nodi. A∗ pesato (f = g + W h) rinuncia all'ottimalità per espandere meno nodi. Per i problemi in cui conta solo lo stato finale esiste la ricerca locale (hill climbing, simulated annealing, beam search, algoritmi genetici). In appendice, cenni di ricerca avversaria (minimax e potatura alfa-beta).Ricerca informata - greedy best-first, A* ed euristiche →. Fonte: slide del corso di Intelligenza Artificiale, Ing. dell'Informazione UniPD, con le implementazioni Python del laboratorio 3.
Agente risolutore di problemi
Un agente risolutore di problemi (problem-solving agent) è un caso particolare di agente basato su obiettivi che pianifica in anticipo: considera sequenze di azioni che portano a un obiettivo. Usa una rappresentazione atomica: uno stato è una scatola nera che cattura tutta l'informazione necessaria, senza strutture interne da esaminare. Le soluzioni si cercano tra sequenze stato azione, spesso su grafi.
Esempio: la Romania. Si è in vacanza in Romania, ad Arad; il volo parte domani da Bucarest. Il ciclo è: (1) formulare l'obiettivo: essere a Bucarest; (2) formulare il problema: stati = le città, azioni = guidare tra città; (3) cercare una soluzione: una sequenza di città, per esempio Arad Sibiu Fagaras Bucarest; (4) eseguire la sequenza di azioni.
La fase 3 è offline: si simula l'esplorazione senza muoversi, e si esegue il piano solo dopo averlo trovato (in un ambiente deterministico, osservabile e noto, Agenti intelligenti - ambienti, PEAS e tipi di agenteUn agente è una funzione dalle sequenze di percezioni alle azioni; è razionale se per ogni sequenza sceglie l'azione che massimizza il valore atteso della misura di prestazione, date le percezioni e la conoscenza incorporata. L'ambiente di lavoro si descrive con PEAS (Performance, Environment, Actuators, Sensors) e si classifica con sette coppie di proprietà (osservabile, deterministico, episodico, statico, discreto, singolo/multi-agente, noto). Le architetture crescono in complessità: reattivo semplice, reattivo basato su modello, basato su obiettivi, basato su utilità, più l'agente che apprende (elemento esecutivo, di apprendimento, critico, generatore di problemi).Agenti intelligenti - ambienti, PEAS e tipi di agente →).
La mappa del laboratorio (posizioni dalle coordinate del notebook, distanze in chilometri) è questa, con in evidenza il cammino ottimo da Arad () a Bucarest ():
Grafico interattivo: Mappa della Romania del laboratorio: i numeri sono i chilometri tra città vicine, in evidenza il cammino di costo minimo da A (Arad) a B (Bucarest)
Le lettere sono le iniziali usate nel codice: A Arad, B Bucarest, C Craiova, D Drobeta, E Eforie, F Fagaras, G Giurgiu, H Hirsova, I Iasi, L Lugoj, M Mehadia, N Neamt, O Oradea, P Pitesti, R Rimnicu Vilcea, S Sibiu, T Timisoara, U Urziceni, V Vaslui, Z Zerind.
Formulazione di un problema
Definizione. Un problema è definito da:
- l'insieme degli stati possibili (lo spazio degli stati, un grafo);
- lo stato iniziale (per esempio "in Arad");
- uno o più stati obiettivo, descritti in modo esplicito ("in Bucarest") o implicito (
NoDirt(x), nessuna sporcizia), con un test dell'obiettivois_goal(s);- le azioni:
Actions(s)è l'insieme delle azioni applicabili in (Actions(Arad)= {verso Timisoara, verso Zerind, verso Sibiu});- il modello di transizione:
Result(s, a)è lo stato raggiunto applicando in (Result(Arad, verso Zerind)= Zerind);- la funzione di costo delle azioni , supposta , e il costo del cammino come somma dei costi dei passi (somma di distanze, numero di azioni eseguite, ecc.).
Una soluzione è una sequenza di azioni che porta dallo stato iniziale a uno stato obiettivo; una soluzione ottima è quella di costo minimo.
La scelta di che cosa mettere nello stato è una astrazione del mondo reale: si tiene solo ciò che serve al problema (nella Romania non conta il meteo).
Esempi di formulazione
Mondo dell'aspirapolvere. Stati: posizione del robot e sporcizia (trascurando la quantità). Quanti? posizioni configurazioni di sporco . Qualunque stato può essere iniziale. Azioni: Left, Right, Suck, NoOp. Modello di transizione: quello descritto dal grafo delle 8 configurazioni. Obiettivo: nessuna sporcizia. Costo: 1 per azione (0 per NoOp).
Puzzle dell'8 (8-puzzle). Stati: la posizione intera delle 8 tessere e dello spazio vuoto. Azioni: muovere lo spazio vuoto a sinistra, destra, su, giù (4 azioni al massimo, sono meno ai bordi). Costo: 1 per mossa. Obiettivo: una configurazione assegnata. Le configurazioni sono , ma raggiungibili da una data sono solo la metà, , per una proprietà di parità delle permutazioni.
Assemblaggio robotico. Stati: coordinate reali degli angoli dei giunti e parti dell'oggetto già assemblate. Azioni: moti continui dei giunti. Modello: modelli cinematici e dinamici. Obiettivo: assemblaggio completo. Costo: tempo di esecuzione. Qui lo spazio è continuo (Agenti intelligenti - ambienti, PEAS e tipi di agenteUn agente è una funzione dalle sequenze di percezioni alle azioni; è razionale se per ogni sequenza sceglie l'azione che massimizza il valore atteso della misura di prestazione, date le percezioni e la conoscenza incorporata. L'ambiente di lavoro si descrive con PEAS (Performance, Environment, Actuators, Sensors) e si classifica con sette coppie di proprietà (osservabile, deterministico, episodico, statico, discreto, singolo/multi-agente, noto). Le architetture crescono in complessità: reattivo semplice, reattivo basato su modello, basato su obiettivi, basato su utilità, più l'agente che apprende (elemento esecutivo, di apprendimento, critico, generatore di problemi).Agenti intelligenti - ambienti, PEAS e tipi di agente →).
Commesso viaggiatore (Travelling Salesperson Problem, TSP). Ogni vertice di un grafo va visitato (le città di una mappa, oppure i fori da praticare con una trapanatrice automatica sulle schede a circuito stampato).
8 regine. Mettere 8 regine su una scacchiera senza che nessuna ne attacchi un'altra. Si può formulare in due modi, con spazi di dimensioni molto diverse.
Formulazione 1 (incrementale ingenua). Stato: qualunque disposizione di 0-8 regine; iniziale: scacchiera vuota; azione: aggiungere una regina in una qualsiasi casella vuota; obiettivo: 8 regine sulla scacchiera e nessuna attaccata. Le sequenze da esaminare sono
Formulazione 2 (migliore). Si vieta di mettere una regina in una casella già attaccata. Stato: disposizioni di regine (), una per colonna nelle colonne più a sinistra, con nessuna regina che ne attacca un'altra; azione: aggiungere una regina in una casella della colonna vuota più a sinistra che non sia attaccata. Gli stati diventano 2057, e le soluzioni si trovano facilmente. Il numero si verifica contando con un programma (ricorsione sulle colonne): 2057 stati, di cui 92 soluzioni complete.
La lezione: la formulazione conta quanto l'algoritmo. La seconda riduce lo spazio di nove ordini di grandezza.
Alberi di ricerca e frontiera
Si simula l'esplorazione dello spazio degli stati generando i successori degli stati già esplorati (espandere uno stato).
function Tree-Search(problem, strategy) returns a solution, or failure
initialize the search tree using the initial state of problem
loop do
if there are no candidates for expansion then return failure
choose a leaf node for expansion according to strategy
if the node contains a goal state then return the corresponding solution
else expand the node and add the resulting nodes to the search treeStati e nodi
Definizione. Uno stato è (la rappresentazione di) una configurazione fisica. Un nodo è una struttura dati che fa parte dell'albero di ricerca e contiene: stato, genitore (parent), azione che l'ha generato, figli, profondità e costo del cammino .
Gli stati non hanno genitore, figli, profondità o costo. Due nodi diversi possono contenere lo stesso stato (si arriva alla stessa città per strade diverse). Nel codice del laboratorio Node(state, parent, action, path_cost); la lunghezza len(node) è la profondità, e path_states, path_actions risalgono i genitori per ricostruire il cammino.
Frontiera
I nodi non ancora espansi (le foglie) formano la frontiera (frontier): separa lo spazio degli stati in due regioni, visitata e non visitata. Esempio nella Romania da Arad: frontiera iniziale ; dopo aver espanso Arad ; dopo aver espanso Sibiu . Arad ricompare: nell'albero lo stesso stato può tornare, e senza controlli la ricerca può girare in tondo (Arad Sibiu Arad ).
Due regole:
- Il test dell'obiettivo si fa quando il nodo viene scelto per l'espansione, non quando entra nella frontiera. È necessario per la correttezza della ricerca a costo uniforme (si vede sotto); la ricerca in ampiezza può farlo prima, alla generazione, come fa il codice del laboratorio.
- Una strategia è determinata dall'ordine in cui si sceglie il nodo da espandere.
Ricerca su albero e ricerca su grafo
La versione sopra è la ricerca su albero (tree search): ignora che gli stati si ripetono. La ricerca su grafo (graph search) aggiunge una tabella reached degli stati già raggiunti con il costo migliore trovato finora: un figlio entra nella frontiera solo se il suo stato non è mai stato raggiunto, oppure se ora è raggiunto con un costo minore. Nel codice del laboratorio:
def best_first_search(problem, f):
"Search nodes with minimum f(node) value first."
node = Node(problem.initial)
frontier = PriorityQueue([node], key=f)
reached = {problem.initial: node}
while frontier:
node = frontier.pop()
if problem.is_goal(node.state):
return node
for child in expand(problem, node):
s = child.state
if s not in reached or child.path_cost < reached[s].path_cost:
reached[s] = child
frontier.add(child)
return failureexpand genera i figli di un nodo e PriorityQueue estrae l'elemento con minima (è uno heap, Code con prioritàEntry chiave-valore; ADT coda con priorità (insert, min, removeMin) con chiave minima = priorità massima; esempio di esecuzione; applicazioni; implementazioni con lista non ordinata e ordinata e relativi costi; ordinamento tramite coda con priorità.Code con priorità →). Il grafo di ricerca è quello delle Grafi - definizioni e proprietàGrafo G=(V,E) diretto e non diretto, grafo semplice e pesato; incidenza, adiacenza, grado; cammini, cicli, sottografi, grafi connessi e componenti connesse; alberi liberi, foreste, spanning tree e spanning forest; proprietà con dimostrazioni (somma dei gradi = 2m, m <= n(n-1)/2, alberi m = n-1, connessi m >= n-1, foreste m <= n-1).Grafi - definizioni e proprietà → e le visite sono le stesse di 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 →, con in più i costi.
Valutare una strategia
Quattro criteri:
- completezza: se esiste una soluzione, la trova sempre?
- ottimalità: trova sempre quella di costo minimo?
- complessità in tempo: proporzionale al numero di nodi generati o espansi;
- complessità in spazio: massimo numero di nodi in memoria.
Tempo e spazio si esprimono con tre parametri:
- = fattore di diramazione massimo (branching factor) dell'albero di ricerca;
- = profondità della soluzione di costo minimo;
- = profondità massima dello spazio degli stati (può essere ).
Ricerca non informata
Le strategie non informate usano solo le informazioni della definizione del problema: non sanno "quanto è lontano" l'obiettivo. Sono sei.
Ricerca in ampiezza (breadth-first search, BFS)
Si espande il nodo meno profondo non ancora espanso. La frontiera è una coda FIFO (first in, first out): i nuovi successori vanno in fondo. Funziona se tutte le azioni hanno lo stesso costo.
Sull'albero binario completo di profondità 3 delle slide (A radice; B, C figli di A; D, E figli di B; F, G figli di C; H, I figli di D; J, K di E; L, M di F; N, O di G), con obiettivo , le frontiere sono: e l'ordine di espansione è (13 nodi). Con goal test alla generazione si ferma appena viene generato espandendo .
Proprietà:
- Completa: sì, se è finito.
- Tempo: .
- Spazio: , perché tiene in memoria ogni nodo. È il vero problema (a e servono nodi).
- Ottima: sì se il costo dei passi è 1 (più in generale costante); non in generale. Trova il cammino con meno passi, non quello più economico.
Ricerca a costo uniforme (uniform-cost search, UCS, algoritmo di Dijkstra)
Si espande il nodo di costo minimo nella frontiera, che è una coda con priorità ordinata per costo del cammino. Equivale alla ricerca in ampiezza se tutti i passi costano uguale, ed è l'algoritmo di Dijkstra (Cammini minimi e algoritmo di DijkstraGrafi pesati, lunghezza di un cammino e distanza; sottocammini di un cammino minimo; problema SSSP; algoritmo di Dijkstra con cloud e priority queue, rilassamento degli archi, esempio svolto; correttezza (due lemmi) e complessità O(min(n^2, (n+m) log n)) con lista non ordinata o heap; pesi non negativi.Cammini minimi e algoritmo di Dijkstra →) fermato quando si estrae l'obiettivo.
Esempio (slide): da Sibiu a Bucarest. Costi tra città dalla mappa.
- Sibiu (g=0) viene espansa. I successori sono Rimnicu Vilcea (80), Fagaras (99) e, tornando indietro, Arad (140) e Oradea (151).
- Il minimo è Rimnicu Vilcea (80): si espande e si aggiunge Pitesti () e Craiova ().
- Il minimo è Fagaras (99): si espande e si aggiunge Bucarest con costo . Non ci si ferma: l'obiettivo si controlla all'estrazione, non all'inserimento.
- Seguono Arad (140) e Oradea (151) (che non portano a nulla di meglio: la slide li omette), poi si espande Pitesti (177) e si genera un secondo cammino verso Bucarest, di costo .
- : il cammino Sibiu Rimnicu Vilcea Pitesti Bucarest sostituisce quello per Fagaras.
- Si espandono ancora Zerind (215), Craiova (226), Timisoara (258); poi Bucarest (278) è estratta con il costo minore ed è riconosciuta come obiettivo.
Soluzione: Sibiu, Rimnicu Vilcea, Pitesti, Bucarest, costo 278. L'esecuzione in Python (grafo con tabella
reached) dà questo ordine di espansione: Sibiu, Rimnicu Vilcea, Fagaras, Arad, Oradea, Pitesti, Zerind, Craiova, Timisoara, Bucarest.
Proprietà:
- Completa: sì se ogni passo costa almeno (così i cammini diventano sempre più costosi e non si resta bloccati su cammini a costo zero).
- Ottima: sì, perché i nodi sono espansi in ordine crescente di : il primo obiettivo estratto ha costo minimo.
- Tempo e spazio: possono essere molto peggiori di per passi piccoli; con costo della soluzione ottima e il costo minimo di un passo, sono , perché esplora tutti i cammini di costo fino a , e non solo quelli corti.
Ricerca in profondità (depth-first search, DFS)
Si espande il nodo più profondo non ancora espanso. La frontiera è una pila LIFO (last in, first out): i successori si mettono in testa. Sullo stesso albero: con ordine di espansione (12 nodi).
Proprietà:
- Non completa: fallisce negli spazi a profondità infinita e in quelli con cicli. Si corregge evitando gli stati ripetuti lungo il cammino o fissando una profondità massima (ricerca a profondità limitata).
- Tempo: ; pessimo se , ma può essere molto più veloce dell'ampiezza se le soluzioni sono dense.
- Spazio: , lineare, : si tiene solo il cammino corrente con i fratelli non espansi (al più nodi).
- Non ottima: si ferma alla prima soluzione trovata.
Nella Romania, DFS da Arad a Bucarest dipende dall'ordine con cui si provano i vicini. Con i vicini in ordine alfabetico trova Arad Sibiu Fagaras Bucarest (costo 450) espandendo 4 nodi; con l'ordine inverso trova Arad Zerind Oradea Sibiu Rimnicu Vilcea Pitesti Bucarest, di costo 575, dopo aver espanso 12 nodi (con il controllo dei cicli sul cammino): ottimo non è, e dipende dalla fortuna.
Ricerca a profondità limitata (depth-limited search)
È la DFS con una profondità massima : i nodi a profondità non si espandono. Restituisce "fallimento" se non esiste soluzione, "cutoff" se il limite ha tagliato qualcosa. Tempo , spazio . Non è completa se ; non è ottima se .
Ricerca ad approfondimento iterativo (iterative deepening search, IDS)
Si esegue la ricerca a profondità limitata con finché si trova la soluzione (o non si ha più "cutoff"). Sull'albero binario con obiettivo :
| limite | nodi espansi (in ordine) | esito |
|---|---|---|
| 0 | cutoff | |
| 1 | cutoff | |
| 2 | cutoff | |
| 3 | trovato |
Combina i vantaggi: completa (come l'ampiezza), spazio (come la profondità), ottima se i costi dei passi sono uguali.
Rifare le iterazioni precedenti sembra uno spreco, ma il costo è dominato dall'ultimo livello. I nodi del livello sono generati volte:
Esempio (slide). , , soluzione nella foglia più a destra: , . Il sovraccosto è il circa, .
Per questo l'IDS è la strategia non informata di scelta quando lo spazio è grande e la profondità della soluzione è ignota.
Ricerca bidirezionale
Due ricerche simultanee, una in avanti dallo stato iniziale e una all'indietro dall'obiettivo, con ampiezza o costo uniforme; ha successo quando le due frontiere si incontrano. Il motivo: . Con e : contro .
- Completa se e lo spazio sono finiti; tempo e spazio ; ottima se i costi sono uguali.
- Si applica bene a problemi con un solo stato obiettivo (il miglior percorso da Arad a Bucarest). Con più obiettivi espliciti (due stanze pulite nel mondo dell'aspirapolvere) si aggiunge uno stato obiettivo fittizio i cui predecessori immediati sono tutti gli obiettivi veri. Se l'obiettivo è una descrizione astratta ("nessuna regina ne attacca un'altra") è difficile da usare.
- Sulla Romania da Arad a Bucarest (ampiezza dai due lati, alternando) le frontiere si incontrano a Fagaras dopo 3 espansioni in tutto (contro 5 dell'ampiezza semplice).
Tutte le strategie sono best-first search
Il codice di best_first_search sopra sceglie sempre il nodo con minimo. Cambiando solo si ottengono le strategie:
def g(n): return n.path_cost
def uniform_cost_search(problem): return best_first_search(problem, f=g)
def breadth_first_bfs(problem): return best_first_search(problem, f=len) # profondità
def depth_first_bfs(problem): return best_first_search(problem, f=lambda n: -len(n)) # profondità negata
def greedy_bfs(problem, h=None): return best_first_search(problem, f=h or problem.h)
def astar_search(problem, h=None): return best_first_search(problem, f=lambda n: g(n) + (h or problem.h)(n))len(n) è la profondità del nodo. Le versioni "vere" della ricerca in ampiezza e in profondità del laboratorio (breadth_first_search con coda FIFO e iterative_deepening_search) sono più efficienti: non pagano la priority queue e la prima fa il test dell'obiettivo alla generazione. Il laboratorio è svolto in Esercizio - Algoritmi di ricerca in Python con Problem, Node e best-first search (laboratorio 3); le due ricerche informate sono nella nota seguente.
Sulla Romania del laboratorio, con Arad e Bucarest, uniform_cost_search restituisce il cammino ['A', 'S', 'R', 'P', 'B'] (costo ), mentre breadth_first_search restituisce ['A', 'S', 'F', 'B']: meno passi (3) ma costo maggiore, . È la differenza tra ottimalità sui passi e sul costo.
Confronto
| strategia | completa | ottima | tempo | spazio |
|---|---|---|---|---|
| ampiezza | sì (se finito) | sì se costi uguali | ||
| costo uniforme | sì (se passi ) | sì | ||
| profondità | no (cicli, profondità infinita) | no | ||
| profondità limitata | no se | no | ||
| approfondimento iterativo | sì | sì se costi uguali | ||
| bidirezionale | sì | sì se costi uguali |
Sulla Romania (da Arad a Bucarest, vicini in ordine alfabetico, nodi espansi con la ricerca su grafo):
| strategia | cammino | costo | espansioni |
|---|---|---|---|
| ampiezza | Arad, Sibiu, Fagaras, Bucarest | 450 | 5 |
| costo uniforme | Arad, Sibiu, Rimnicu Vilcea, Pitesti, Bucarest | 418 | 13 |
| profondità (con controllo dei cicli) | Arad, Sibiu, Fagaras, Bucarest | 450 | 4 |
| approfondimento iterativo | Arad, Sibiu, Fagaras, Bucarest | 450 | 18 (somma delle iterazioni) |
Il costo uniforme espande più nodi di tutti (esplora in ogni direzione fino a costo 418), ma è l'unico, con l'ampiezza sui passi, a garantire la soluzione ottima: per spendere meno serve l'informazione di Ricerca informata - greedy best-first, A* ed euristicheLa ricerca informata usa una funzione euristica h(n) che stima il costo da n all'obiettivo. Greedy best-first espande il nodo con h minima (f = h): veloce ma non ottima né in generale completa. A∗ usa f = g + h e, con h ammissibile (mai sopra il costo vero) e, sul grafo con tabella dei raggiunti, consistente, è completa e ottima; il fattore di diramazione effettivo b∗ misura la qualità di h, e un'euristica che ne domina un'altra espande meno nodi. A∗ pesato (f = g + W h) rinuncia all'ottimalità per espandere meno nodi. Per i problemi in cui conta solo lo stato finale esiste la ricerca locale (hill climbing, simulated annealing, beam search, algoritmi genetici). In appendice, cenni di ricerca avversaria (minimax e potatura alfa-beta).Ricerca informata - greedy best-first, A* ed euristiche →.
Domande d'esame
- Con e quanti nodi genera, al più, la ricerca in ampiezza (soluzione nell'ultima foglia) e quanti l'approfondimento iterativo? BFS ; IDS .
- Con la ricerca a costo uniforme da Sibiu a Bucarest, qual è il costo della soluzione e perché non ci si ferma quando Bucarest entra nella frontiera? Costo 278 (Sibiu, Rimnicu Vilcea, Pitesti, Bucarest). Bucarest entra la prima volta con costo (via Fagaras), ma poi si trova : il test dell'obiettivo si fa all'estrazione dalla coda, quando il costo è minimo.
- Quanta memoria usa la ricerca in profondità con e (al massimo)? Il cammino corrente più i fratelli non espansi: nodi, contro nodi dell'ultimo livello.
- Perché la ricerca bidirezionale è più efficiente? Quanto vale con , ? Ciascuna delle due ricerche arriva solo a profondità : nodi invece di .
- Quanti stati ha la formulazione migliore delle 8 regine? 2057 (una regina per colonna a sinistra, nessuna attaccata) contro sequenze della prima.
Versione ripasso
- Agente risolutore di problemi: agente basato su obiettivi con rappresentazione atomica (lo stato è una scatola nera). Ciclo: formulare l'obiettivo, formulare il problema, cercare (offline, simulando), eseguire. Esempio: Arad Sibiu Fagaras Bucarest (Agenti intelligenti - ambienti, PEAS e tipi di agenteUn agente è una funzione dalle sequenze di percezioni alle azioni; è razionale se per ogni sequenza sceglie l'azione che massimizza il valore atteso della misura di prestazione, date le percezioni e la conoscenza incorporata. L'ambiente di lavoro si descrive con PEAS (Performance, Environment, Actuators, Sensors) e si classifica con sette coppie di proprietà (osservabile, deterministico, episodico, statico, discreto, singolo/multi-agente, noto). Le architetture crescono in complessità: reattivo semplice, reattivo basato su modello, basato su obiettivi, basato su utilità, più l'agente che apprende (elemento esecutivo, di apprendimento, critico, generatore di problemi).Agenti intelligenti - ambienti, PEAS e tipi di agente →).
- Problema: stati; stato iniziale; obiettivo (esplicito "in Bucarest" o implicito
NoDirt(x), testis_goal);Actions(s); modello di transizioneResult(s, a); costo e costo del cammino additivo (somma di distanze, numero di azioni). Soluzione: sequenza di azioni dall'iniziale a un obiettivo; ottima se di costo minimo. Lo stato è un'astrazione: si tiene solo ciò che serve. - Esempi: aspirapolvere stati (azioni
Left,Right,Suck,NoOp, costo 1, 0 perNoOp); puzzle dell'8: azioni = muovere il vuoto, costo 1, stati raggiungibili; assemblaggio robotico: spazio continuo, costo = tempo; TSP: visitare ogni vertice; 8 regine: formulazione 1 (aggiungi una regina in una casella vuota) sequenze, formulazione 2 (una regina per colonna a sinistra, non attaccata) 2057 stati, di cui 92 soluzioni. - Nodo = stato + genitore + azione + profondità + costo ; due nodi possono avere lo stesso stato, uno stato no (non ha genitore né costo). Frontiera = foglie non espanse; separa regione visitata e non. Test dell'obiettivo all'espansione, non all'inserimento (l'ampiezza può farlo alla generazione). Nella Romania da Arad: : Arad ricompare, ci vuole il controllo dei ripetuti.
- Ricerca su grafo: tabella
reached; un figlio entra nella frontiera solo se il suo stato è nuovo o raggiunto con costo minore. Codice:node = frontier.pop(); seis_goalrestituisci; per ogni figlio diexpand, ses not in reached or child.path_cost < reached[s].path_costaggiornareached[s]efrontier.add(child)(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 →, Code con prioritàEntry chiave-valore; ADT coda con priorità (insert, min, removeMin) con chiave minima = priorità massima; esempio di esecuzione; applicazioni; implementazioni con lista non ordinata e ordinata e relativi costi; ordinamento tramite coda con priorità.Code con priorità →, Grafi - definizioni e proprietàGrafo G=(V,E) diretto e non diretto, grafo semplice e pesato; incidenza, adiacenza, grado; cammini, cicli, sottografi, grafi connessi e componenti connesse; alberi liberi, foreste, spanning tree e spanning forest; proprietà con dimostrazioni (somma dei gradi = 2m, m <= n(n-1)/2, alberi m = n-1, connessi m >= n-1, foreste m <= n-1).Grafi - definizioni e proprietà →). - Criteri: completezza, ottimalità, tempo, spazio, con (diramazione massima), (profondità della soluzione ottima), (profondità massima, anche ).
- Ampiezza (coda FIFO, espande il meno profondo): ; completa, ottima se costi uguali (non in generale: meno passi, non costo minore), tempo , spazio , il vero limite.
- Costo uniforme (coda con priorità su ; è Dijkstra, Cammini minimi e algoritmo di DijkstraGrafi pesati, lunghezza di un cammino e distanza; sottocammini di un cammino minimo; problema SSSP; algoritmo di Dijkstra con cloud e priority queue, rilassamento degli archi, esempio svolto; correttezza (due lemmi) e complessità O(min(n^2, (n+m) log n)) con lista non ordinata o heap; pesi non negativi.Cammini minimi e algoritmo di Dijkstra →): completa se passi , ottima (espande in ordine crescente di ), tempo e spazio . Esempio Sibiu Bucarest: espande Sibiu (0), Rimnicu Vilcea (80), Fagaras (99), Arad (140), Oradea (151), Pitesti (177), Zerind (215), Craiova (226), Timisoara (258), Bucarest (278). Bucarest entra con , poi con sostituisce il precedente: costo 278, perché il test si fa all'estrazione.
- Profondità (pila LIFO): , ordine ; non completa (cicli, profondità infinita; si rimedia con controllo sul cammino o limite), non ottima, tempo , spazio (al più nodi). Arad Bucarest: costo 450 (4 espansioni) o 575 (12) secondo l'ordine dei vicini.
- Profondità limitata : "cutoff" se il limite taglia; incompleta se , non ottima se ; tempo , spazio .
- Approfondimento iterativo: limiti ; completa, ottima se costi uguali, spazio , ; , : contro dell'ampiezza (sovraccosto ). Sull'albero binario con obiettivo : limiti 0, 1, 2 tagliano, il limite 3 trova .
- Bidirezionale: una ricerca dallo stato iniziale e una dall'obiettivo che si incontrano, tempo e spazio (, : contro ); ottima se costi uguali; richiede un solo obiettivo (con più obiettivi si inserisce uno stato obiettivo fittizio), difficile con obiettivi astratti.
- Tutte sono best-first search con diversa: UCS ; ampiezza profondità; profondità profondità (Esercizio - Algoritmi di ricerca in Python con Problem, Node e best-first search (laboratorio 3)). Romania del laboratorio, A B: UCS
['A','S','R','P','B'], costo ; ampiezza['A','S','F','B'], costo . - Confronto sulla Romania (Arad Bucarest, nodi espansi): ampiezza 450 (5), costo uniforme 418 (13), profondità 450 (4), approfondimento iterativo 450 (18 in totale). Il costo uniforme espande di più ma è ottimo; per spendere meno serve l'informazione (Ricerca informata - greedy best-first, A* ed euristicheLa ricerca informata usa una funzione euristica h(n) che stima il costo da n all'obiettivo. Greedy best-first espande il nodo con h minima (f = h): veloce ma non ottima né in generale completa. A∗ usa f = g + h e, con h ammissibile (mai sopra il costo vero) e, sul grafo con tabella dei raggiunti, consistente, è completa e ottima; il fattore di diramazione effettivo b∗ misura la qualità di h, e un'euristica che ne domina un'altra espande meno nodi. A∗ pesato (f = g + W h) rinuncia all'ottimalità per espandere meno nodi. Per i problemi in cui conta solo lo stato finale esiste la ricerca locale (hill climbing, simulated annealing, beam search, algoritmi genetici). In appendice, cenni di ricerca avversaria (minimax e potatura alfa-beta).Ricerca informata - greedy best-first, A* ed euristiche →).
- Numeri da saper rifare: , : ampiezza nodi, IDS ; DFS con , : nodi in memoria contro dell'ultimo livello; bidirezionale , : invece di ; 8 regine: stati contro sequenze.
- Errori tipici: fermarsi quando l'obiettivo entra nella frontiera nel costo uniforme; dire che l'ampiezza è ottima in generale (solo con costi uguali); dire che la profondità è completa senza controllo dei cicli; dimenticare le iterazioni precedenti dell'IDS; confondere (profondità della soluzione) con (profondità massima dello spazio); contare lo spazio dell'IDS come quello dell'ampiezza.
Esercizi su questo argomento
- Esercizio - Algoritmi di ricerca in Python con Problem, Node e best-first search (laboratorio 3)
- Esercizio - Ambienti, PEAS e tipo di agente (slide del corso)
- Esercizio - Confronto degli algoritmi di ricerca con CountCalls, report e grafici (laboratorio 3)
- Esercizio - Euristiche dell'8-puzzle e fattore di diramazione effettivo (slide del corso)
- Esercizio - Formulazione delle 8 regine, hill climbing e simulated annealing (slide del corso)
- Esercizio - Programmazione a oggetti in Python - listino, carrello, copie e ristorante (laboratorio 2)
- Esercizio - Ricerca di costo uniforme, greedy e A* sulla mappa della Romania (slide del corso)
- Esercizio - Route finding sulla Romania e pancake sorting con euristica del gap (laboratorio 3)