Avatar billede troublesmurf Praktikant
31. marts 2006 - 13:38 Der er 7 kommentarer

Sudoku optimering

Jeg har lavet en sudoku-solver via den velkendte backtracking algoritme.
Jeg har dog erfaret at det spiller en væsentlig performance-mæssig rolle fra sudoku til sudoku om jeg tager rækker eller kolonner først(3-8 gange hurtigere).
Jeg vil derfor lave en check-metode som vælger hvilken fremgangsmåde der skal benyttes, men jeg kan ikke finde ud af hvilke kriterier jeg skal undersøge.

Jeg har forsøgt at tælle antal blanke felter i rækker/kolonner og så vælge ud fra det, men dette er ikke løsningen. Ej heller at tælle blanke felter i første halvdel virker.

Jeg efterlyser ikke kode, men blot det matematiske bag hvordan man kan vælge løsningsmetoden.

Mit program ser i pseudo-kode nogenlunde sådan ud:

recursive_method(X, Y)
  for a = 1 to 9
    if is_allowed(board[X][Y] = a)
      board[X][Y] = a
      recursive_method(X+1, Y)

   
Hvor forskellen så ligger i om jeg kalder X+1 eller Y+1

but why?!?
Avatar billede jakoba Nybegynder
31. marts 2006 - 14:40 #1
3-8 gange er ingenting. det er andre steder der skal optimeres hvis det skal batte noget.
Avatar billede troublesmurf Praktikant
31. marts 2006 - 16:12 #2
resten er optimeret og det er også kun denne optimering jeg er interesseret i.
Jeg er nede på 0.4 millisekund.
Avatar billede jakoba Nybegynder
01. april 2006 - 20:57 #3
Nej det er resten pokkerme ikke:

recursive_method(X, Y)
  short allowed = is_allowed( X, Y );  // check all 9 med eet kald
  for a = 1 to 9;
    if ( (allowed & 1<<a) != 0 )
      board[X][Y] = a;
      recursive_method(X+1, Y);
                    // jeg går ud fra du smider en exception når du er færdig

nedsætter antallet af subroutinekald fra 18 til 10
nedsætter antallet af 2D indexeringer fra 9*21+n til 20+n

og de tests der skal udføres indeni is_allowed bliver såvidt jeg kan se også simplere. (du skal blot sørge for at allerede brugte tal in række X og kolonne Y og gruppe X,Y ikke har deres bit sat i den short der returneres.)

mvh JakobA
Avatar billede troublesmurf Praktikant
01. april 2006 - 22:02 #4
Min pseudo-kode er kun en simpel beskrivelse af at jeg bruger recursive backtracking. Det er ikke en egentlig beskrivelse af hvordan testene virker. Som før nævnt er det eneste jeg er ude efter at finde ud af hvordan jeg kan teste for hvordan mit "board" virker.
Desuden lignede min kode lidt det du skrev. Men det havde dårligere performance end det jeg bruger nu.
Men som førnævnt er det altså KUN hvordan jeg checker for hvordan boardet skal vende...
Avatar billede jakoba Nybegynder
01. april 2006 - 22:18 #5
OK. Så må jeg nok vige pladsen for jeg ser ikke nogen måde at forudsige hvilken vej der er bedst at gå.
Avatar billede erikjacobsen Ekspert
01. april 2006 - 22:24 #6
Sudoku er helt symmetrisk mht rækker og søjler, men det kan have en vis virkning i hvilken rækkefølge du tester i din is_allowed.

Der er andre ting man kan overveje, om som andre allerede har overvejet (google er din ven....), såsom i hvert trin at starte med at lede efter de felter, hvor der kun er een mulighed, og tage den som næste felt. Dvs du ikke skal tage felterne i en på forhånd given rækkefølge. Det koster lidt at lede efter felter med een mulighed, men til gengæld gør man rekursionstræet mindre. Andre har prøvet, og jeg mener ikke konklusionen er helt klar.

Når du siger du kan klare det på 0.4 ms er det vel en konkret sudoku-opgave - der burde være forskel på nemme og svære i løsningstid.
Avatar billede troublesmurf Praktikant
02. april 2006 - 09:10 #7
Erik >> Det har du så ganske ret i.
Det er en opgave vi blev stillet i skolen(for at vise vi kan backtracke), hvorefter der så er gået sport i at lave den bedste algoritme og test-sekvens. Med opgaven var givet en sudoku-opgave. Af uforklalige årsager var min algoritme hurtigst, indtil vi opdagede at jeg løste den omvendt.
Vi troede så at det kunne hjælpe at tælle blanke felter i første række, kontra første kolonne, da der var en væsentlig forskel i det antal. Men det gjorde sig ikke gældende på andre opgaver.
Nu tester jeg rækker og kolonner i samme metode og firkanter i en seperat da det skar lidt af tiden i alle tilfælde.

Mener du at det vil hjælpe at tælle antal muligheder i de første 3 felter? Det forslag har nemlig også været oppe, men vi ville mene det tager alt for lang tid iforhold til hvad der er sparet.

At lave en "intelligent" test af opgaven som du foreslår har alt for store omkostninger, hvertfald på de lette opgaver, men som før nævnt har det ret stor betydning hvordan brædtet vender, og en test af første række/kolonne betyder stort set intet for løsningstiden.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester