zaterdag 3 maart 2012

Conclusie

Als gevolg van de resultaten kunnen we beschouwen dat een computer even geschikt is als onze hersennen voor het oplossen van een sudoku. Het moet stapsgewijs gebeuren en de computer doe het sneller, immers omdat het voor deze berekening werd "gespecialiseerd" aan de hand van een programma.

Het gaat om de oplossingen voor lege vakken steeds opnieuw te checken a.h.v. meerdere functie, waarbij de centrale hart van de programma de functie only_one() is. Deze zal immers oplossingen valideren. De andere functies zijn er dan om het aantal oplossingen te beperken door eliminatie.

In totaal krijgen we de hiërachie:

-readfile('tekst') #lees de tekst document
-classify('lijnen') #zet de lijnen om tot een lijst van matrices met een bepaalde sleutel (=dictionary)
-solve(grids): #meesterfunctie die de sudoku's zal oplossen. Eerst worden de lege vakken "geregistreerd".
      while not test = = empties: #de volgende functies werden in een loop gezet die op ieder moment checkt
                                              #als de functies nog iets veranderen aan de oplossingen
            #functie voor validatie van oplossingen
            -only_one(grid,empties)
            #functies voor eliminatie van oplossingen
            -X_Wings(empties)
            -align(empties)
            -double(empties)
-check('oplossingen') #ga na of er geen fout is opgetreden in de programma (bv. twee keer '4' in een rij)
-cum_sum('oplossingen','coördinaten') #berekent de totale som van de cijfers gevormd door bepaalde    
                                                           #vakken
-write_new('oplossingen','bestandsnaam') #schrijft de oplossingen in een nieuw tekst document

Er werden oorspronkelijk ook andere functies gemaakt maar deze werden verwijderd doordat ze overbodig waren. Voor sudoku's met een hogere moeilijkheidsgraad zullen ze misschien wel bruikbaar kunnen worden.

donderdag 1 maart 2012

Tijd in functie van de sudokus

Hieronder bevindt zich een tabel met de tijd die het programma nodig heeft om bepaalde sudokus op te lossen. De moeilijkheidsgraad geeft aan hoe lang de computer ten opzichte van de langste tijd met een sudoku bezig was.

Sudoku|   t(s) | Moeilijkheid
1 0,155 4,23%
2 0,161 4,40%
3 0,219 5,96%
4 0,167 4,56%
5 0,14 3,81%
6 1,237 33,70%
7 0,427 11,63%
8 0,168 4,59%
9 0,313 8,53%
10 2,284 62,26%
11 0,231 6,29%
12 0,161 4,40%
13 0,298 8,11%
14 0,184 5,01%
15 0,287 7,83%
16 0,112 3,04%
17 0,109 2,97%
18 0,188 5,12%
19 0,181 4,93%
20 0,165 4,49%
21 0,193 5,27%
22 0,279 7,61%
23 0,201 5,47%
24 0,207 5,65%
25 1,455 39,66%
26 0,316 8,61%
27 0,217 5,92%
28 0,213 5,82%
29 0,296 8,07%
30 0,225 6,13%
31 0,285 7,77%
32 0,224 6,11%
33 0,168 4,59%
34 0,172 4,70%
35 0,175 4,77%
36 0,171 4,67%
37 0,173 4,72%
38 0,174 4,73%
39 0,172 4,70%
40 0,173 4,71%
41 0,312 8,50%
42 2,861 77,96%
43 1,147 31,26%
44 0,42 11,46%
45 0,298 8,13%
46 0,331 9,01%
47 2,79 76,05%
48 0,428 11,67%
49 3,342 91,08%
50 3,669 100,00%
tot 28,27

Bron

Voor het vinden van sudokumethodes werd het volgende bron gebruikt:
http://ffsudoku.com/techniques.html

Het is een zeer bruikbare site voor wie aan sudoku's wil beginnen. Op deze methodes heb ik mijn verschillende functies gebaseerd en omgevormd tot een door de computer te begrijpen "taal".

Cumulatieve som

Met behulp van een zelfgemaakte functie cum_sum() heb ik de som van de getallen gevormd door de eerste drie cijfers van elke sudoku kunnen berekenen: deze is 24702.

#som van de cijfers gevorm door resp. vakken R1K1, R1K2 en R1K3
#van elke sudoku
>>> cum_sum(solutions,["00","01","02"])


24702

maandag 27 februari 2012

Align Align... Align Align...

Eindelijk heb ik de laatste functie kunnen aanmaken: de functie align()

Het methode berust op het feit dat als er binnen een grote vak (=regio) één cijfer alleen maar mogelijk is binnen een bepaalde rij of kolom, dan is dit cijfer niet mogelijk voor de vakken van dezelfde rij of kolom buiten de regio.


Gebruik makend van deze laatste functie bekom ik:

>>> solve(grids)

solved grids:  50/50
time:  34.887 s

Daarna heb ik een verificatiefunctie check() aangemaakt. Deze geeft mij aan als er een of meerdere problemen zijn in de verschillende sudoku's en of alles juist is.

>>> check(solutions)

All completed

Double was a double agent...

Nadat ik eventjes de oplossingen die ik kreeg bij het toepassen van mijn functie double() bekeek, zag ik met veel teleurstelling dat iets niet klopte. Ik ben dus op de definitie van de doubletmethode terug gegaan en zag dat ik de variant slecht had begrepen: er moet immers geen andere vak bestaan die in dezelfde entiteit de ene of de andere waarde bevat van de twee vakken (zie post: It gets harsh!).

Ik heb dit aangepast en zelfs de functies triple() en quad() op basis daarvan aangemaakt. Het is dezelfde principe als bij de double() functie maar dan met drie/vier waarden en vakken.

Het resultaat was onthutsend:

>>> solve(grids)



solved grids:  49/50
time:  32.956 s

Tot nu toe gebruikte stappenplan.

Op het laatste moment heb ik opgemerkt dat ik mijn stappenplan ben vergeten op te schrijven. Ik dacht immers geen "exacte plan" te gebruiken maar gewoon functies één per één aan te maken die mij tot mijn doel zouden kunnen brengen. Kort zou ik mijn stappenplan kunnen formuleren als volgt:

1) Txt-bestand met de sudoku's omzetten tot een lijst van 9x9 matrices.
2) Lijst aanmaken van candidaten van de lege vakken, gekoppeld met hun positie in de matrices.
3) Sudokumethodes vinden en omzetten in bruikbare functies. (t.e.m. het einde)
4) Eens dat er oplossingen gevonden zijn, deze in een nieuw txt-document opschrijven
5) Een testfunctie aanmaken die uittest als de oplossingen wel kloppen.
6) Optellen van elke 3-cijfers nummer in de linkertop van elke sudokus. (extra, als alle sudoku's zijn opgelost)