CMD + K

Kapittel 10Begreper & formler · CSP II: backtracking og lokalt søk
Referanseside · Kapittel 10

Begreper & referanser

Alle nøkkelbegrepene, formlene og referansene fra CSP II: backtracking og lokalt søk, samlet på én side. Bruk denne som oppslag når du leser, øver flashcards eller tar quiz.

Øv med flashcards18 kort fra dette kapittelet

Begreper

Sentrale begreper fra kapittelet med korte definisjoner.

01Backtracking-søk

Dybde-først-søk som gir én variabel en verdi om gangen, forkaster verdier som bryter en begrensning mot de tilordnede variablene, og trekker tilbake forrige tilordning når en variabel går tom for verdier (backtracking search).

02Kommutativitet

Egenskapen at rekkefølgen tilordningene gjøres i, ikke endrer resultatet. Derfor holder det å velge én variabel per nivå, og søketreet får blader i stedet for (commutativity).

03MRV-heuristikken

Velg som neste variabel den som har færrest lovlige verdier igjen. Har en variabel null lovlige verdier, oppdages blindveien straks. På norsk: minste gjenværende verdier (minimum remaining values, MRV).

04Gradheuristikken

Velg variabelen med flest begrensninger mot variabler som ikke er tilordnet ennå. Brukes særlig som tie-break når MRV gir likhet (degree heuristic).

05Minst begrensende verdi

Prøv først verdien som fjerner færrest lovlige verdier hos de ikke-tilordnede naboene, med laveste verdi ved likhet (least constraining value, LCV).

06Feil først og feil sist

Prinsippet bak MRV og LCV: velg variabelen som mest sannsynlig feiler, fordi alle må tilordnes uansett, men verdien som minst sannsynlig feiler, fordi én løsning er nok (fail-first, fail-last).

07Fremoversjekking

Etter hver tilordning fjernes verdiene hos de ikke-tilordnede naboene til som er inkonsistente med . Blir et nabodomene tomt, forkastes straks (forward checking, FC).

08MAC

Å opprettholde buekonsistens under søket: etter tilordningen kjøres AC-3 med buene for de ikke-tilordnede naboene , og propageringen fortsetter så langt den rekker (maintaining arc consistency, MAC).

09Min-conflicts

Lokalt søk for CSP: start med en komplett tilordning, velg en tilfeldig variabel i konflikt, og gi den verdien med færrest konflikter. Svært raskt når løsningene ligger tett, men ikke fullstendig (min-conflicts).

10Trestrukturert CSP

Et CSP der begrensningsgrafen er et tre. Det kan løses i uten tilbakesteg ved å gjøre buene konsistente fra bladene og tilordne fra roten. Utenfor pensum 2026 (tree-structured CSP).

11Topologisk rekkefølge

En rekkefølge av nodene i et tre med valgt rot der hver node kommer etter forelderen sin. Brukes i algoritmen for trestrukturerte CSP (topological sort).

Formler

Hver formel: hva den heter, hvordan den ser ut, og hva symbolene betyr.

backtracking-blader

Antall blader i søketreet

Uten kommutativitet kan hver ledig variabel få hver verdi på hvert nivå, så forgreningen er på nivå . Med én variabel per nivå er forgreningen . Vanlig feil er å svare .

nantall variabler
dantall verdier per variabel
mrv

MRV-valget

Lovlige verdier er verdiene som ikke bryter en begrensning mot de tilordnede variablene, eller domenet etter FC. Ved likhet brukes gradheuristikken og så laveste indeks, med mindre oppgaven sier noe annet.

D_X^lovligverdiene X fortsatt kan få
min-conflicts

Min-conflicts-trekket

Variabelen er valgt tilfeldig blant dem som er i konflikt, og får verdien som bryter færrest begrensninger med de andres nåværende verdier. Ved likhet trekkes en av de beste, og den nåværende verdien kan være med.

Xen variabel i konflikt
konflikter(X, v)antall brutte begrensninger hvis X får verdien v
tre-csp-kompleksitet

Kjøretiden for trestrukturerte CSP

Gjelder bare når begrensningsgrafen er et tre: buer gjøres konsistente, hver for , og tilordningen etterpå går uten tilbakesteg. Utenfor pensum 2026.

nantall variabler
ddomenestørrelse

Kodesnutter

Kodesnutter fra kapittelet, vist literal.

Kode

Backtracking på 14 dronninger med MRV og FC

Python
bruk_mrv = 0  # @param 0..1bruk_fc = 0  # @param 0..1 n = 14  # variabel = kolonne, verdi = radforsok = tilbake = 0  def kolliderer(k1, r1, k2, r2):    return r1 == r2 or abs(r1 - r2) == abs(k1 - k2)  def los(tilordning, domener):    global forsok, tilbake    if len(tilordning) == n:        return tilordning    ledige = [k for k in range(n) if k not in tilordning]    lovlige = {k: [r for r in domener[k] if not any(kolliderer(k, r, j, s) for j, s in tilordning.items())]               for k in ledige}    k = min(ledige, key=lambda j: len(lovlige[j])) if bruk_mrv else ledige[0]    for r in lovlige[k]:        forsok += 1        nye = domener        if bruk_fc:  # fjern verdier hos de ledige som kolliderer med k = r            nye = {j: [s for s in domener[j] if not kolliderer(k, r, j, s)] for j in ledige if j != k}            if any(not d for d in nye.values()):                continue  # et domene ble tomt: forkast verdien        svar = los({**tilordning, k: r}, nye)        if svar:            return svar    tilbake += 1  # k gikk tom: tilbake til forrige variabel    return None  svar = los({}, {k: list(range(1, n + 1)) for k in range(n)})print(f"Løsning: {', '.join(str(svar[k]) for k in range(n))}" if svar else "Løsning: ingen")print(f"Tilordninger forsøkt: {forsok}")print(f"Tilbakesteg: {tilbake}")

Prøv: sett bruk_mrv til 1 og se at linja Tilordninger forsøkt: faller fra 1899 til 124, og sett så bare bruk_fc til 1 og se at Tilbakesteg: faller til under halvparten.

Kode

Min-conflicts på n dronninger

Python
import random random.seed(4)n = 8  # @param 4..40maks_steg = 100  # @param 10..1000 rad = [random.randrange(n) for _ in range(n)]  # tilfeldig start: rad[k] i kolonne k  def konflikter(k, r):    return sum(1 for j in range(n) if j != k and (rad[j] == r or abs(rad[j] - r) == abs(j - k)))  lost_etter = Nonefor steg in range(maks_steg + 1):    i_konflikt = [k for k in range(n) if konflikter(k, rad[k]) > 0]    if not i_konflikt:        lost_etter = steg        break    if steg == maks_steg:        break    k = random.choice(i_konflikt)  # tilfeldig variabel i konflikt    tall = [konflikter(k, r) for r in range(n)]    rad[k] = random.choice([r for r in range(n) if tall[r] == min(tall)])  # likhet: tilfeldig par = sum(1 for a in range(n) for b in range(a + 1, n) if rad[a] == rad[b] or abs(rad[a] - rad[b]) == b - a)print(f"Løst etter steg: {lost_etter}" if lost_etter is not None else f"Løst etter steg: ikke løst innen {maks_steg} steg")print(f"Konflikter igjen: {par}")

Prøv: øk n til 40 og se at linja Løst etter steg: fortsatt havner under 100, og senk maks_steg til 10 og se at Konflikter igjen: blir større enn 0.

Pseudokode

Pseudokode som forklarer fremgangsmåten steg for steg.

Pseudokode

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 valg

Tre 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.

Læringsmål

Hva du skal kunne etter å ha lest kapittelet.

  1. 01Forklar hvordan backtracking-søk bygger delvise tilordninger, og hvorfor kommutativitet gir blader i stedet for
  2. 02Spor backtracking med MRV, gradheuristikken og laveste indeks, og oppgi tilordningsrekkefølgen og antall tilbakesteg
  3. 03Velg verdi med LCV ved å telle hvor mange verdier hver kandidat fjerner hos de ikke-tilordnede naboene
  4. 04Skriv alle domener etter hver tilordning med fremoversjekking, og marker forkastede verdier og tilbakesteg
  5. 05Sammenlign fremoversjekking og MAC, og forklar hva MAC oppdager som FC ikke ser
  6. 06Beskriv min-conflicts, og vurder når lokalt søk slår systematisk søk