2 svar
118 visningar
Ygolopot behöver inte mer hjälp
Ygolopot 215
Postad: 20 jul 2021 11:23

Rekursion, hur tilldelningen på en variabel skiljer sig mellan "nivåerna" i rekursionen

Hej, pillar med lite klassiska rekursioner för att vänja mig vid Python. Har kollat på en tutorial för backtracking algoritm för att lösa Sudoku och har en grej jag hakar upp mig lite på:

Här är själva rekursionen

def solve(bo):
    #Base case
    find = find_empty(bo)
    if not find:
        return True
    else:
        row, col = find
    #Trying solutions
    for i in range(1, 10):
        if valid(bo, i, (row, col)):
            bo[row][col] = i

            if solve(bo):
                return True
            bo[row][col] = 0
    return False

 

In kommer alltså Sudoku-brädan vi ska lösa (kallas bo i programmet), find_empty är en metod för att hitta första lediga plats (ledig plats definierat som en plats med 0 på), om det ej finns så är vi ju klara så då returneras True. I annat fall tilldelas row och col platsen i matrisen där första lediga plats är (går igenom rad för rad). På denna plats börjar jag sen testa i = 1, 2, 3, ... etc. i loopen tills det att min metod "valid" ger grönt ljus för att det är en ok siffra i enlighet med Sudoku-reglerna. Efter detta dyker vi ner i rekursionen och börjar om, alltså:

Kollar om vi är klara, om ej --> Plockar nästa första lediga plats --> Testar i = 1, 2, 3, ... etc tills första som passar.

När det är så att inget tal i [1,9] passar så returneras False, och vi kommer tillbaka på nivån innan. 

Det jag inte fattar är dock hur talen på row,col ändras. Exempel på board:

board = [
[7, 8, 0, 4, 0, 0, 1, 2, 0],
[6, 0, 0, 0, 7, 5, 0, 0, 9],
[0, 0, 0, 6, 0, 1, 0, 7, 8],
[0, 0, 7, 0, 4, 0, 2, 6, 0],
[0, 0, 1, 0, 5, 0, 9, 3, 0],
[9, 0, 4, 0, 6, 0, 0, 0, 5],
[0, 7, 0, 3, 0, 0, 0, 1, 2],
[1, 2, 0, 0, 0, 7, 4, 0, 0],
[0, 4, 9, 2, 0, 6, 0, 0, 7]
]

 

Anta att vi startar på "level 1",

Level 1:

Första lediga plats är (row, col) = (0,2)  --> Första som passar är 3 och det tilldelas på bo[0][2]--> Dyker ner i solve(bo) och kommer till level 2:

 

Level 2:

Första lediga plats (row, col) = (0,4) --> första som passar är 9 och det tilldelas på bo[0][4] --> Dyker ner igen in solve(bo), kommer till "level 3"

 

Level 3:

Första lediga plats (row, col) =(0,5) -->INGEN passar, return False -->tillbaka i level 2 på raden där det står bo[row][col]=0

Här tappar jag bort mig, för det senast tilldelade värdet på (row, col) är ju (0,5) och det borde därför vara så att vi sätter

bo[0][5] = 0, som alltså redan är 0 då det inte blev tilldelat något värde eftersom inget tal mellan 1 och 9 passade. Detta borde följas med att vi returnerar False igen eftersom vi var på sista loopen i level 2 (fick ju precis in 9), kommer till level 1, sätter återigen bo[0][5] = 0, och forsätter i loopen i level 1, alltså testar i = 4 härnäst på plats (0,5).

 

Det som händer dock är att när vi kommer tillbaka till level 2 så återfår (row,col) värdena (0,4). Det är som att (row,col) har olika värden i de olika nivåerna snarare än att hela tiden ha det senaste tilldelade, och det är det jag inte hänger med på för tycker inte det känns logiskt. Stämmer detta eller missar jag att dom tilldelas (0,4) någonstans?

Sorry om det blev en rörig förklaring för tycker det emellanåt är stökigt med rekursion men från Java har jag för mig att det inte är såhär men jag är nybörjare så har säkert fel... Känns inte logiskt iaf att row, col är något annat än senast tilldelade.

Hoppas någon kan hjälpa till att reda ut, tack på förhand :)

Laguna Online 30696
Postad: 20 jul 2021 12:56 Redigerad: 20 jul 2021 13:02

Jag ska läsa det hela noggrannare senare, men jag tror jag kan svara på en sak: row och col är lokala variabler, så de kan inte förändras av några funktionsanrop, inte heller om variablerna har samma namn, och inte ens om det till synes är "samma" variabler när funktionen anropar sig själv. Varje funktionsanrop får sina egna kopior av variablerna.

Edit: det är precis likadant i Java.

Ett annat fall är när man inte använder lokala variabler utan attribut till en instans av en klass. Då arbetar man med en viss instans och då är det samma attribut (bara ett annat namn för variabler som hör till en instans) hela tiden. 

Ygolopot 215
Postad: 20 jul 2021 15:41

Aha!! Fattar nu. Tack så mycket! :)

Svara
Close