Ricerca non informata Corso di Intelligenza Artificiale, a.a. 2017-2018 Prof. Francesco Trovò 05/03/2018
Ricerca non informata Definizione del problema della ricerca Architettura necessaria Blind search techniques
Agente risolutore di problemi Agente basato su obbiettivi hanno una valutazione interna del fatto che l obbiettivo sia stato raggiunto Rappresentazione atomica dello stato Dobbiamo generare una sequenza di azioni atomiche per raggiungere un dato stato obbiettivo A priori dobbiamo dare: Formulazione obbiettivo: determinare la situazione corrente e quella in cui l obbiettivo è raggiunto Formulazione problema: decisione obbiettivo, azioni e stati da considerare
Esempio: raggiungere Bucarest partendo da Arad
Proprietà dell ambiente Completamente osservabile / parzialmente osservabile Agente singolo / multiagente Deterministico / stocastico Episodico / sequenziale Statico / dinamico / semidinamico Discreto / continuo Noto / ignoto
Formulazione problema Soluzione: elenco di azioni che specificano cosa compiere in quale stato (banale in questo caso, non in generale) Ricerca: analisi di sequenze di azioni per trovare una soluzione Esecuzione: attuazione della soluzione trovata precedentemente Formulazione del problema: Insieme degli stati Stato iniziale Azioni ammissibili (in ogni stato) Modello di transizione (grafo) Test obbiettivo Costo di passo Soluzione ottima: soluzione con costo di cammino minima
Esempio viaggio Formulazione del problema: Insieme degli stati: città raggiungibili Stato iniziale: Arad Azioni ammissibili (in ogni stato): determinate dai collegamenti Modello di transizione (grafo): deterministico, il nuovo stato corrisponde alla città di arrivo Test obbiettivo: positivo solo a Bucharest Costo di passo: distanza tra due città
Cercare soluzioni Formalizziamo il processo di ricerca con un albero di ricerca: Nodi stati nello spazio degli stati del problema Archi azioni Ad ogni passo verificheremo che il nodo raggiunto non sia un nodo obbiettivo In caso negativo dobbiamo espandere lo stato corrente per comprendere nuovi nodi stato I nuovi nodi saranno figli degli stati correntemente considerati
Iniziando da Arad Arad Frontiera Sibiu Timisoara Zerind Arad Fagaras Oradea Rimnicu Vilcea Attenzione: la sequenza Arad, Sibiu, Arad, Sibiu,... continua all infinito albero di profondità infinita Ricerca: scelta di quale degli stati della frontiera espandere ulteriormente
Evitare i cicli Il processo di espansione viene iterato fino a che non si raggiunge uno stato obbiettivo Affinchè il processo sia efficace dobbiamo definire una strategia di ricerca Con questa rappresentazione potremmo anche espandere lo stesso nodo più volte Mantenendo un insieme che contiene i nodi esplorati posso ovviare al problema (ricerca su grafo), dove la frontiera è quell insieme di nodi che divide i nodi esplorati da quelli inesplorari
Dall idea all implementazione Una volta capito che cosa dobbiamo fare per risolvere il problema dovremo operativamente scrivere un programma che lo risolva Decidere le strutture dati (per i nodi, la frontiera) Valutare se l algoritmo è valido per il problema affrontato Nel caso medio Nel caso pessimo In termini temporali In termini spaziali
Stuttura dati nodo Ogni nodo deve avere specificato: Lo stato corrispondente Un puntatore al nodo padre (che l ha generato) Un azione (applicata al padre per ottenere il nodo) Un costo di cammino (dallo stato iniziale al nodo corrente) Esempio: Fagaras - Fagaras - Sibiu - Vai a Fagaras - 140+99 = 239 Così trovata una soluzione possiamo trovare la sequenza di azioni per ragggiungerla
Rappresentazione della frontiera Nella frontiera devo poter: Controllare se è vuota (la ricerca finisce) Estrarre un elemento (FIFO, LIFO, priorità) Inserire un elemento La scelta di appropriate strutture dati può rendere la ricerca più o meno efficiente (e.g., tabella hash per controllare facilemente gli stati ripetuti) Fondamentale che si definisca una forma canonica dei dati che renda facile il controllo dell uguaglianza tra nodi
Valutazione dell algoritmo Per determinare se un algoritmo è valido per risolvere un problema dovremo verificare la sua: Completezza: garantisce di trovare una soluzione Ottimalità: la soluzione trovata è ottima (rispetto al costo di cammino) Complessità temporale: numero di passi utilizzati per arrivare alla soluzione Complessità spaziale: quantità di dati utilizzati durante l esecuzione La complessità solitamente è espressa in termini di dimensioni del grafo che spesso è infinito, quindi valutiamo: b branching factor d profondità (depth) m lunghezza massima dei cammini
Efficienza di un algoritmo di ricerca A seconda del problema possiamo considerare come misura di efficienza dell algoritmo di ricerca: Costo della ricerca: costo temporale per trovare una soluzione più potenzialmente un costo relativo alla memoria utilizzata Costo totale: costo temporale della ricerca e costo del cammino corrispondente alla soluzione trovata Non è detto che due algoritmi siano facilmente confrontabili (non esiste una conversione km e sec nel caso del viaggio)
Blind search Se non abbiamo informazioni sul problema dobbiamo utilizzare una delle tecniche di ricerca non informata Non ho altre informazioni riguardo i nodi se non quella data dalla definizione del problema Ricerca in ampiezza Ricerca a costo uniforme Ricerca in profondità Raffinamenti Più avanti vedremo anche algoritmi di ricerca informata (o euristica)
Ricerca in ampiezza (breadth first)
Ricerca in ampiezza (breadth first) Idea: non espando un nodo prima che quelli sul livello superiore dell albero siano già tutti stati espansi Implementabile facilmente con una lista FIFO sulla frontiera Il test obbiettivo è applicato quando il nodo viene generato e non quando viene espanso (risparmio un livello di espansione) Sto implicitamente cercando dei cammini il più corti possibili (in termine di azioni)
Analisi ricerca in ampiezza Completezza: se il branch factor è finito arrivo alla soluzione meno profonda (se esiste) Ottimalità: non necessariamente (sì se le azioni hanno tutte lo stesso costo) Complessità temporale: b + b 2 + b 3 = O(b d ) Complessità spaziale: O(b d 1 ) nodi esplorati, O(b d ) nodi inesplorati con b = 10, 1 ns per il controllo di un nodo, 1 kbyte per nodo Profondità Nodi Tempo Memoria 4 11.100 11 ms 10.6 MB 6 10 6 1.1 s 1 GB 8 10 8 2 min 103 GB 10 10 10 3 h 10 TB 12 10 12 13 d 1 PB
Ricerca a costo uniforme
Ricerca a costo uniforme Se i costi sono tutti uguali la ricerca in ampiezza e a costo uniforme coincidono In questo caso il test obbiettivo viene attuato quando è selezionato per l espansione Infatti: se il nodo viene aggiunto più volte alla frontiera viene scelto il cammino a costo minimo
Analisi ricerca a costo uniforme Completezza: se il branch factor è finito e ogni passo ha costo almeno ε, arrivo alla soluzione Ottimalità: vado a selezionare la soluzione con costo di cammino minore (se ne esistesse un altro l avrei espanso prima) Definiamo C costo del cammino ottimo e ε costo minimo di cammino C 1+ Complessità temporale: O(b ε ) C 1+ Complessità spaziale: O(b ε ) Idea: esploro prima i nodi con costo piccolo e poi quelli con costo grande
Ricerca in profondità
Ricerca in profondità (su albero)
Ricerca in profondità Anche in questo caso possiamo implementare l algoritmo di ricerca come una coda LIFO L implementazione più diretta utilizza la ricorsione sui figli per generare la soluzione (a patto di mettere un controllo sulla profondità massima) Se utilizziamo una ricerca su grafo arriviamo ad espandere l intero spazio, con la ricerca su albero potrebbe rimanere in un loop
Analisi della ricerca in profondità Completezza: su grafo è completa, su albero no Ottimalità: non ottimale Definiamo m profondità massima di un cammino (potenzialmente molto più profonda di quella della soluzione ottima) Complessità temporale: O(b m ) Complessità spaziale: O bm Backtracking: espando un solo nodo alla volta invece che tutti e segno quali azioni ho già fatto Richiede una memoria di O m nodi
Ricerca a profondità limitata Nel caso in cui m sia infinito la ricerca in profondità fallisce Idea: limitare la profondità massima l Potremmo impostare una profondità troppo piccola e introdurre dell incompletezza nell algoritmo Se conosco il diametro del problema posso impostare quello come profondità massima Spesso non ho informazioni relative al diametro finchè non risolvo il problema
Ricerca ad approfondimento iterativo Idea: provo a trovare la soluzione con profondità massima l = 1, se non la trovo provo con l = 2, se non la trovo provo con l = 3, etc. Completezza: come la ricerca in ampiezza Ottimalità: trova la soluzione con profondità minima Complessità temporale: db + d 1 b 2 + + b d = O(b d ) poichè passo sugli stessi nodi più volti Complessità spaziale: O bd come la ricerca in profondità
Ricerca bidirezionale Riduzione della ricerca in ampiezza a O(b d 2) Problema: richiede di conoscere esplicitamente lo stato obbiettivo