Backtracking-søk
Et CSP kan løses som et vanlig søkeproblem: starttilstanden er den tomme tilordningen, en handling gir en ikke-tilordnet variabel en verdi, og målet er en komplett, konsistent tilordning. Gjort naivt blir treet enormt. På første nivå kan hvilken som helst av de variablene få hvilken som helst av de verdiene, så forgreningen er , deretter og så videre. Treet får blader, selv om det bare finnes ulike komplette tilordninger.
Nøkkelen er kommutativitet (commutativity): rekkefølgen tilordningene gjøres i, endrer ikke resultatet. og så gir samme tilordning som og så . Det holder derfor å velge én variabel på hvert nivå og forgrene bare på verdiene. Da får treet blader i stedet for , se ƒantall blader i søketreet.
Algoritmen backtracking-søk (backtracking search) er dybde-først-søk i dette treet. Den velger en variabel, prøver verdiene i tur og orden og går videre med den første som ikke bryter en begrensning mot variablene som alt er tilordnet. Går en variabel tom for verdier, trekkes forrige tilordning tilbake, og forrige variabel prøver sin neste verdi. Det er et tilbakesteg. Søket lagrer bare én delvis tilordning om gangen, så minnet er lineært i . Algoritmen er fullstendig: finnes en løsning, finner den den, og finnes ingen, slår den fast det etter å ha prøvd hele treet. Verken MRV, LCV eller propageringen senere i kapitlet endrer det. De endrer bare hvor raskt svaret kommer.
Backtracking-søk i pseudokode
tilbakespor(tilordning, domener): hvis alle variabler har en verdi: returner tilordning x = velg_variabel(tilordning, domener) # fast, MRV, MRV + grad for v i ordne_verdier(x, tilordning, domener): # fast eller LCV hvis v passer med alle tilordnede naboer: legg til x = v nye = utled(x, v, domener) # ingenting, FC eller MAC hvis ingen domener i nye er tomme: svar = tilbakespor(tilordning, nye) hvis svar ikke er feil: returner svar fjern x = v # prøv neste verdi returner feil # tilbake til forrige valgTre valg styrer søket: hvilken variabel som tas, i hvilken rekkefølge verdiene prøves, og hvor mye som utledes etter hver tilordning. Strukturen er etter Russell & Norvig, slik den ligger i aimacode/aima-pseudocode (CC BY 4.0), oversatt og med egne navn.
Figuren bruker eksamensplanen fra kapittel 9, med fast variabelrekkefølge og dagene i stigende rekkefølge.
Prøv: gå fram til Etikk står uten lovlig dag, og se hvilken tilordning søket trekker tilbake.
Planen viser svakheten ved fast rekkefølge. Databaser får dag 1 uten at søket ser på Etikk, og først når Etikk skal tilordnes, viser det seg at ingen dag kommer før dag 1. Feilen ble gjort ett nivå opp, men oppdages ett nivå ned. I større problemer kan avstanden være mange nivåer, og søket kan bruke lang tid på å prøve alt under en tilordning som var dømt fra starten.
To ord holdes fra hverandre i resten av kapitlet. En verdi som bryter en begrensning mot en tilordnet nabo, forkastes på stedet og blir aldri tilordnet. Et tilbakesteg skjer først når en variabel har prøvd alle verdiene sine, og en tidligere tilordning må trekkes tilbake. Eksamensoppgaver som spør etter antall tilbakesteg, teller det siste.
RegneeksempelKjør backtracking med fast rekkefølge K, L, M, N og verdiene i stigende rekkefølge, og tell tilbakestegene.Vis løsningSkjul løsning
Domener: K {2, 3}, L {1, 2, 3}, M {1, 2}, N {1, 2, 3}
Begrensninger: M < L, K ≠ L, L ≠ N, M ≠ NSteg 1. . Ingen tilordnede naboer, så verdien er konsistent.
Steg 2. er konsistent med .
Steg 3. må være mindre enn . Verken 1 eller 2 passer, så går tom. Tilbakesteg: trekkes tilbake.
Steg 4. bryter . er konsistent.
Steg 5. passer med . bryter , mens passer med både og .
Steg 6. Løsningen er , , , , funnet med ett tilbakesteg.
Hvorfor holder det at backtracking-søk velger én variabel på hvert nivå i søketreet?
Kjør backtracking uten inferens. Variablene tilordnes i fast rekkefølge Q, R, S, T, og verdiene prøves i stigende rekkefølge. En verdi som bryter en begrensning mot en tilordnet variabel, forkastes uten å telle. Et tilbakesteg er hver gang søket må trekke tilbake tilordningen til en tidligere variabel fordi neste variabel har gått tom for verdier. Hvor mange tilbakesteg tar søket før det finner en løsning?
Variabler: Q, R, S, T, alle med domene {1, 2, 3}
Begrensninger: R < Q, R = T, T < S, Q ≠ TEt CSP har 4 variabler med 3 verdier hver. Søket formuleres naivt: på hvert nivå kan hvilken som helst ikke-tilordnet variabel få hvilken som helst verdi, uten å sjekke begrensningene. Hvor mange blader har søketreet?