Sökning Sökning ! Datastrukturer och operationer Datastruktur: ! Värdering av sökstrategier nod = ! Blind sökning [tillstånd, förälder, operator, djup, vägkostnad] ! Heuristisk sökning Expandera varje nod ! Constraint satisfaction ! Spelförande program Applicera operatorer på ett tillstånd och generera alla nya tillstånd Ex: Initialtillståndet (0, 0) expanderas till (4, 0) och (0, 3) (4, 0) expanderas till (0, 0) (4, 3) (1, 3) (0, 3) expanderas till (0, 0) (4, 3) (3, 0) etc. Sökstrategi avgör vilken nod som skall expanderas Köoperationer Sökalgoritmer sparar noder som skall expanderas i en kö Typiska köoperationer: ! empty?(queue) ! pop(queue) ! insert(element, queue) Generell sökalgoritm def treeSearch(problem): frontier = insert(initialState(problem), frontier) while true: if empty?(frontier): return failure node = pop(frontier) if goalTest(problem, state(node)): return solution(node) frontier = insert(expand(node, problem), frontier) Nodexpansion Värdering av sökstrategi Expand(node, problem) ! Komplett Skapa en lista av noder, s, som är efterföljare till en nod, n, där: state[s] = tillståndet efter uförd legal handling i n parent-node[s] = n ! hittar lösning om den finns ! Optimal ! hittar bästa lösningen action[s] = handlingen som utfördes ! Tidsåtgång vägkostnad[s] = vägkostnad[n] + kostnad från n till s ! Minnesåtgång djup[s] = djup[n] + 1 Blind sökning Bredden först Ingen information om hur långt det är kvar till målet ! Expandera alla noder på en nivå innan nästa nivå ! Bredden först 1 ! Uniform cost 2 ! Djupet först ! Djupbegränsad sökning ! Iterativ fördjupning 3 4 8 5 9 10 6 11 12 7 13 14 15 ! Dubbelriktad sökning ! Implementeras med insert som en FIFO-kö Bredden först Bredden först ! Komplett Antag lösning på djupet d, då har vi expanderat: ! Optimal 1+b+b2+b3+b4+b5+………..bd noder ! Komplexitet ett problem Vid komplexitetsanalys säger vi att vi har O(bd), dvs exponentiell tillväxt ! Förgreningsfaktor b ! Sökdjup d T Ex b=2 d=0, en nod, b0 1 2 d=1, b1 noder 3 d 4 8 5 9 10 6 11 12 d=2, b2 noder 7 13 14 15 d=3, b3 noder Bredden först, tids- och minneskomplexitet Djup Noder 2 110 4 Tid Uniform Cost Minne 0,11 ms 0,1 MB 11110 11 ms 10,6 MB 6 106 1.1 s 1 GB 8 108 2 min 103 GB 10 1010 3 timmar 10 TB 12 1012 13 dagar 1 PetaByte 14 1014 3,5 år 99 PetaByte 16 1016 350 år 10 ExaByte Förgreningsfaktor = 10, 1 miljon noder/sekund, 1000 bytes/nod ! Om inte alla operatorer har samma kostnad A 1 ! Expandera billigaste vägen längs frontier 5 S B 15 A 1 B 5 S S C 15 A M 11 B 5 C 15 A B M 11 M 10 C 15 ! Optimal och komplett om det inte finns negativa kostnader ! I princip O(bd) för tids- och minneskomplexitet M 5 C S 10 5 Djupet först Djupet först ! Följer alltid en väg till slutet, om inte en lösning backa upp ! Kräver mindre minne, m*b där m=maxdjup. ! Jämför b=10,m=12, djupet först = 10*12=120, bredden först = 1012 1 2 4 8 1 3 2 1 3 3 ! Samma tidskomplexitet O(bm) ! Inte optimal 3 ! Inte komplett, kan dyka ner i en oändligt lång sökväg 5 9 1 5 10 6 11 12 7 13 14 15 ! Implementeras med insert som en LIFO-kö, STACK Djupbegränsad sökning Iterativ fördjupning ! Lägg in ett maxdjup, l, för djupet först ! Låt sökdjupet, h, öka från 0 till det djup, d, där en lösning finns ! Tidskomplexitet fortfarande exponentiell, O(bl) ! Minneskomplexitet O(b*l) h=0 ! Inte komplett om man inte kan skatta ett sökdjup som garanterar en lösning, jfr, rumäniengrafen, max 20 städer, dvs l=20 ger komplett ! Inte optimal h=3 h=1 h=2 Iterativ fördjupning Dubbelriktad sökning ! Optimal och komplett ! Sök bredden-först från start och mål samtidigt ! Inte alltid möjligt ! Minneskomplexitet, O(b*d) ! Tidskomplexitet, ! Komplett och optimal O(bd) ! Tids- och minneskomplexitet, lösning djup d ! Expanderar dock noderna flera gånger ! Bredden-först 1+b+b2+b3+b4+b5+………..bd ! 2bd/2, dvs O(bd/2) ! Iterativ fördjupning db+(d-1)b2+(d-2)b3+……+3bd-2+2bd-1+bd ! Ex b=10, d=6 ! Men antal noder på nivå d många fler än resten ! Bredden först, O(bd) = 106 = 1000000 ! Ex b=10, d=5 ! Dubbelriktad sökning = 106/2 = 103 = 1000 ! Bredden först: 1+10+100+1000+10000+100000=111111 ! Iterativ födjupning: 50+400+3000+20000+100000=123450 Egenskaper hos sökstrategier Kriterium Undvika loopar Bredden Uniform först Cost Djupet Djupförst begränsad Iterativ fördjupning Dubbelriktad sökning Komplett? Ja Ja Nej Nej Ja Ja Optimal? Ja Ja Nej Nej Ja Ja Tid O(bd) O(bC*/ε) O(bm) O(bl) O(bd) O(bd/2) Ex vattenhinksproblemet (0,0) (4,0) (0,0) (4,3) (0,3) (1,3) (0,0) (4,3) (3,0) ! Generera inte tillstånd som är lika med fadertillståndet ! Generera inte vägar med cykler Minne O(bd) O(bC*/ε) O(bm) O(bl) O(bd) O(bd/2) ! Behöver bara leta från noden som genererats upp till startnoden ! Generera inte ett tillstånd som genererats förut ! Varje tillstånd måste lagras i minnet, O(bd) Heuristisk sökning Greedy Search ! Antar att vi har någon information om vilken nod som är bäst att expandera ! Minimera uppskattad kostnad till målet, dvs expandra den nod som verkar vara närmast målet ! Greedy search ! Inför h(n)= heuristisk funktion som uppskattar kostnaden från nod n till målet ! A* ! h(n) = 0 betyder att n är målnod ! IDA* och SMA* ! Ex Rumänienkartan ! Heuristik ! Fågelavståndet ett exempel på heuristik ! Hill Climbing h(n)= Arad 366 Bukarest Fagaras 178 Giurgiu 77 Hirsova 0 Craiova 160 Dobreta 242 Eforie 161 151 Iasi 226 Lugoj 244 Mehadia 241 Neamt 234 Oradea 380 Pitesi Sibiu 253 Tisioara 329 Urziceni 80 Vasliu 98 Rimnicu V. Greedy Search, Arad → Bukarest 193 199 Zerind 374 Arad Oradea Neamt Zerind Zerind (374) Iasi Arad Sibiu Fagaras Oradera (380) Vaslui Fagaras (178) Rimnicu Vilcea Timisoara Bukarest (0) Pitesi Lugoj Urziceni Bukarest Mehadia Dobreta Sibiu (253) Craiova Giurgiu Eforie Timisoara (329) Rimnicu Vilcea (193) Greedy Search A* ! Liknar djupet först och kan råka ut för samma problem ! Inte optimal ! Inför f(n) = g(n) + h(n), dvs tillryggalagd kostnad + uppskattad återstående kostnad ! Inte komplett ! Kräv också att h(n) aldrig överskattar den verkliga kostnaden ! Tids- och minneskomplexitet O(bd) men kan ofta bli bättre med god heuristik ! h(n) kallas då tillåten (admissible), ex fågelavståndet ! Jämför Uniform Cost ! Komplett och optimal men ineffektiv ! Inför g(n) för kostnad från start för nod n h(n)= Arad 366 Bukarest Fagaras 178 Giurgiu 77 Hirsova 0 Craiova 160 Dobreta 242 Eforie 161 151 Iasi 226 Lugoj 244 Mehadia 241 Neamt 234 Oradea 380 Pitesi Sibiu 253 Tisioara 329 Urziceni 80 Vasliu 98 Rimnicu V. A*, Arad → Bukarest 193 199 Zerind Arad 374 Oradea Neamt 71 Zerind 151 75 Arad 140 87 Sibiu Zerind f(Zerind) = 75+374 = 449 Iasi Sibiu f(Sibiu) = 140+253=393 92 99 Fagaras Vaslui Oradera (140+151+380=671) Fagaras (140+99+178=417) Timisoara f(Timisoara) = 118+329=447 Rimnicu Vilcea (140+80+193=413) 118 Timisoara 80 Rimnicu Vilcea 97 111 98 Pitesi Lugoj 85 70 146 Mehadia 75 Dobreta 142 211 120 138 101 Urziceni Bukarest (140+99+211+0=450) 86 Bukarest Bukarest (140+80+97+101+0=418) 90 Craiova Giurgiu Pitesi(140+80+97+98=415) Eforie Craiova (140+80+146+160=526) Craiova (140+80+138+160=518) A* är optimal Evalueringsfunktionen i A* ! Antag: lösningsnoden G optimum med kostnad f* och G2 lösning men med kostnad g(G2) > f* f(n) = g(n) + h(n) g(n) = 0 → Greedy search där h(n) = 0 → Uniform Cost f(n) = totalkostnad g(n) = 1 och h(n) = 0 → f(n) = 1, dvs Bredden först ! För att A* skall välja G2 måste det finnas en nod, n, på vägen till G som inte expanderats n G2 G g(n) = kostnad hittills h(n) = uppskattad återstående kostnad (måste underskatta) ! f* ≥ f(n) eftersom h aldrig överskattar (tillåten) ! f(n) ≥ f(G2) eftersom A* expanderat till G2 ! dvs f* ≥ f(G2) ! Eftersom G2 målnod så h(G2) = 0 f(G2) = g(G2) dvs f* ≥ g(G2) vilket motsäger antagandet Heuristik Heuristik, 1 ! Heuristiska sökmetoder bättre med bättre heuristik, dvs bättre skattning av kostnaden ! Antal brickor som ligger fel 1 Ex. 15-spel 1 2 3 2 3 4 2 3 4 5 5 6 6 5 6 6 9 7 9 10 7 13 11 14 14 4 4 7 9 5 8 13 1 8 8 11 3 2 1 10 7 13 12 10 9 12 11 11 14 14 12 10 12 15 15 8 15 15 13 12: (1,3,4,5,6,7,8,9,10,11,12,13,14,15)=14 8: (1,3,4,5,6,7,8,9,10,11,13,14,15)=13 Heuristik, 2 Hill Climbing ! Mahattanavståndet 1 2 3 5 3 6 9 7 9 10 7 13 5 ! Om varje nytt tillstånd innehåller all nödvändiginformation för att gå vidare, dvs vi kan utvärdera en nod utan hänsyn till varifrån vi kom och vägen mindre viktig 8 13 11 11 14 14 4 2 6 4 S 1 12 10 3 12 2 15 15 8 10 12: 4+0+2+1+4+1+3+3+2+1+1+1+4+1+1=29 13 23 12 15 8: 4+0+2+1+4+1+3+2+2+1+1+0+4+1+1=27 30 Hill Climbing Problem för hill climbing def hillClimbing (problem): Lokal metod, hittar lokalt optimum current = makeNode(initialState(problem)) while True: next = highestValuedSuccessor(current) if (value next) <= (value current): return current current = next Lokalt maximum Platå Globalt maximum Ås Constraint satisfaction Ex. trefärgsproblemet Givet: Färga varje stat: • Tre färger • Grannstater olika färg ! En mängd variabler X1,X2,….Xn ! Med värden vi till Xi ur domänen Di ! En mängd begränsningar C1,C2,…Cn ! Som talar om vilka värden som är tillåtna Mål: ! En tilldelning {Xi=vi, Xj=vj …} som är konsistent med begränsningarna Constraint satisfaction sökning Algoritm ! Bredden först skulle tilldela varje variabel ett värde generera ett stort sökträd ! Eftersom ordningen saknar betydelse kan man istället tilldela en variabel ett värde och sen backa tillbaka om det inte blev bra start NT=Röd Q=Röd SA=Röd SA=Blå Q=Blå SA=Grön NT=Blå Q=Grön Ex. {(WA=grön),(NT=blå), (Q=grön),(NSW=blå), (SA=röd),(V=grön),(T=blå)} NT=Grön def backtrackingSearch(csp): return recursiveBacktracking([ ], csp) def recursiveBacktracking(assignment, csp): if complete(assignment): return assignment var = selectUnassignedVariable(variables(csp),assignment,csp) for value in orderDomainValues(var,assignment,csp): if consistent(value,assignment,constraint(csp)): add {var=value} to assignment result = recursiveBacktracking(assignment,csp) if result != failure: return result remove {var=value} from assignment return failure Algoritm Algoritm, forts ! Variabler = [NT, Q, NSW, SA, V, T, WA] ! väljer nytt värde i for-loopen assignment = {Q=blå} ! Värden = [Röd, Blå, Grön] ! recursiveBacktracking({NT=röd, Q=blå}, csp} ! Initialt assignment = { } ! etc ! selectUnassignedVariable väljer variabel ! {NT=röd, Q=blå, NSW=grön} ! Ex var = NT ! orderDomainValues väljer värden enligt någon heuristik ! Ex assignment = {NT = röd} ! Nytt anrop recursiveBacktracking({NT=röd}, csp}) ! var=SA går inte utan det rekursiva anropet ger ett failure ! remove {var=value} from assignment tar bort något värde, t.ex. det sista NSW=grön och sen fortsätter algoritmen med ny variabel ! selectUnassignedVariable väljer var = Q ! orderDomainValues väljer röd. Inte konsistent Heuristik Spelförande program ! Val av variabel och värde ! Minimax ! selectUnassignedVariable bör välja den variabel som är mest begränsad och först väljs den som har flest begränsningar, SA ! orderDomainValues välj det minst begränsande värdet ! Constraint propagation ! Propagera effekten av en variabels begränsningar till de andra variablerna ! Backtrackingstrategier ! Ta bort det värde, eller den variabel, som orsakade konflikten ! Evalueringsfunktioner ! alfa-beta cutoff Minimax Ett sökträd Max X X X X X 8 4 5 X X X X Min O X X O O X X O X X O e(x, , ,x,o, , , , )=4-4=0 X X X O O X e( ,x, ,x,o, , , , , )=0 3 5 O Max X O 8 4 8 9 4 5 9 6 3 9 9 X e( , , ,x,o, , , ,x)=4-3=1 Applicera evaluaeringsfunktion, t.ex.: e(p)=n(vinstdrag för mig) – n(vinstdrag för motståndaren) Evalueringsfunktion 8 7 2 9 1 6 2 4 1 1 3 5 3 9 2 6 5 2 1 2 3 9 7 2 9 6 4 alfa-beta cutoff, 1 n ! Linjär e( p) = ∑ wi fi i=0 ! Ex: e(p)=1*n(vinst för mig)-1*n(motståndarvinst) e(p)=π*n(vinst för mig)-2,18*n(motståndarvinst)+1*n(diagonaler) n ! Icke-linjär e( p) = ∏ fi 2 i=1 ! Inlärning ! Vikter och funktioner lärs in automatiskt utifrån gamla spel ! Credit assignmentproblemet Två tröskelvärden α och β: ! α representerar det lägsta värdet en maxnod kan få, dvs en undre gräns för MAX ! β representerar det högsta värdet en minnod kan få, dvs en övre gräns för MIN alfa-beta cutoff, 2 Ett sökträd ! Initiering: ! α = sämsta värdet; β = bästa värdet Max 8 5 4 ! Tilldelning: ! α = bästa efterföljare hitills, på MAX-nivå ! β = sämsta efterföljare hitills, på MIN-nivå Min 4 8 3 5 ! Regler: ! Avbryt MIN-sökning vid nod med värde mindre än α ! Avbryt MAX-sökning vid nod med värde större än β Max 8 8 7 2 9 9 4 5 9 2 4 1 1 3 5 3 9 6 6 3 1 2 3