Browse Source

added samples; added MRV strategy

master
Robin Thoni 7 years ago
parent
commit
ef16560093

+ 9
- 0
sample/00.txt View File

@@ -0,0 +1,9 @@
1
+462831957
2
+795426183
3
+381795426
4
+173984265
5
+659312748
6
+248567319
7
+926178534
8
+834259671
9
+517643890

+ 1
- 0
sample/04.txt View File

@@ -0,0 +1 @@
1
+.......12........3..23..4....18....5.6..7.8.......9.....85.....9...4.5..47...6...

+ 7
- 0
uqac-ia-sudoku-csp/Board.cs View File

@@ -1,6 +1,8 @@
1 1
 using System;
2
+using System.Collections.Generic;
2 3
 using System.IO;
3 4
 using System.Linq;
5
+using uqac_ia_sudoku_csp.Interfaces;
4 6
 
5 7
 namespace uqac_ia_sudoku_csp
6 8
 {
@@ -93,6 +95,11 @@ namespace uqac_ia_sudoku_csp
93 95
             return !Game.Any(line => line.Any(cell => cell == null));
94 96
         }
95 97
 
98
+        public bool IsConsistent(int x, int y, IList<IConstraint> constraints)
99
+        {
100
+            return constraints.All(constraint => constraint.Check(this, x, y));
101
+        }
102
+
96 103
         public void Print(TextWriter stream)
97 104
         {
98 105
             stream.WriteLine(Characters);

+ 4
- 2
uqac-ia-sudoku-csp/Interfaces/INextValueChooser.cs View File

@@ -1,7 +1,9 @@
1
-namespace uqac_ia_sudoku_csp.Interfaces
1
+using System.Collections.Generic;
2
+
3
+namespace uqac_ia_sudoku_csp.Interfaces
2 4
 {
3 5
     public interface INextValueChooser
4 6
     {
5
-        void SelectVariable(Board board, out int x, out int y);
7
+        void SelectVariable(Board board, out int x, out int y, IList<IConstraint> constraints);
6 8
     }
7 9
 }

+ 7
- 3
uqac-ia-sudoku-csp/Program.cs View File

@@ -1,6 +1,7 @@
1 1
 using System;
2 2
 using uqac_ia_sudoku_csp.Solver;
3 3
 using uqac_ia_sudoku_csp.Solver.Generators;
4
+using uqac_ia_sudoku_csp.Solver.NextValueChoosers;
4 5
 
5 6
 namespace uqac_ia_sudoku_csp
6 7
 {
@@ -13,13 +14,15 @@ namespace uqac_ia_sudoku_csp
13 14
             var generator = new FileGenerator();
14 15
             generator.Generate(board, new FileGeneratorDbo
15 16
             {
16
-                EmptyCharacters = "0 ",
17
-                FilePath = "../sample/03.txt"
17
+                EmptyCharacters = "0 .",
18
+                FilePath = "../sample/04.txt"
18 19
             });
19 20
             board.Print(Console.Out);
20 21
 
21
-            var solver = new BacktrackSearch();
22
+            var solver = new BacktrackSearch(new MRVNextValueChooser());
23
+            var start = DateTime.Now;
22 24
             var resolved = solver.Resolve(board);
25
+            var end = DateTime.Now;
23 26
 
24 27
             if (resolved.Success)
25 28
             {
@@ -31,6 +34,7 @@ namespace uqac_ia_sudoku_csp
31 34
                 Console.WriteLine("Not resolved");
32 35
             }
33 36
             Console.WriteLine($"{resolved.TryCount} tries");
37
+            Console.WriteLine($"{(end - start).TotalMilliseconds} ms");
34 38
         }
35 39
     }
36 40
 }

+ 18
- 41
uqac-ia-sudoku-csp/Solver/BacktrackSearch.cs View File

@@ -1,5 +1,4 @@
1
-using System;
2
-using System.Collections.Generic;
1
+using System.Collections.Generic;
3 2
 using System.Linq;
4 3
 using uqac_ia_sudoku_csp.Interfaces;
5 4
 using uqac_ia_sudoku_csp.Solver.Constraints;
@@ -8,10 +7,12 @@ namespace uqac_ia_sudoku_csp.Solver
8 7
 {
9 8
     public class BacktrackSearch : ISolver
10 9
     {
10
+        private readonly INextValueChooser _nextValueChooser;
11 11
         protected IList<IConstraint> Constraints;
12 12
 
13
-        public BacktrackSearch()
13
+        public BacktrackSearch(INextValueChooser nextValueChooser)
14 14
         {
15
+            _nextValueChooser = nextValueChooser;
15 16
             Constraints = new List<IConstraint>
16 17
             {
17 18
                 new LineContraint(),
@@ -22,61 +23,37 @@ namespace uqac_ia_sudoku_csp.Solver
22 23
 
23 24
         public SolverResult Resolve(Board board)
24 25
         {
26
+            var domain = Enumerable.Range(0, board.Size).ToList();
25 27
             var result = new SolverResult();
26
-            result.Success = RecursiveResolve(board, result);
28
+            result.Success = RecursiveResolve(board, result, domain);
27 29
             return result;
28 30
         }
29 31
 
30
-        protected bool RecursiveResolve(Board board, SolverResult result)
32
+        protected bool RecursiveResolve(Board board, SolverResult result, IList<int> domain)
31 33
         {
32 34
             if (board.IsComplete())
33 35
             {
34 36
                 return true;
35 37
             }
36 38
             int x, y;
37
-            SelectVariable(board, out x, out y);
38
-            foreach (var value in GetDomainValues(board))
39
+            _nextValueChooser.SelectVariable(board, out x, out y, Constraints);
40
+            if (x != -1 && y != -1)
39 41
             {
40
-                ++result.TryCount;
41
-                board.SetNumber(x, y, value);
42
-                if (IsConsistent(board, x, y))
42
+                foreach (var value in domain)
43 43
                 {
44
-                    if (RecursiveResolve(board, result))
44
+                    ++result.TryCount;
45
+                    board.SetNumber(x, y, value);
46
+                    if (board.IsConsistent(x, y, Constraints))
45 47
                     {
46
-                        return true;
48
+                        if (RecursiveResolve(board, result, domain))
49
+                        {
50
+                            return true;
51
+                        }
47 52
                     }
48 53
                 }
54
+                board.ClearNumber(x, y);
49 55
             }
50
-            board.ClearNumber(x, y);
51 56
             return false;
52 57
         }
53
-
54
-        protected void SelectVariable(Board board, out int x, out int y)
55
-        {
56
-            for (var xx = 0; xx < board.Size; ++xx)
57
-            {
58
-                for (var yy = 0; yy < board.Size; ++yy)
59
-                {
60
-                    if (board.GetNumber(xx, yy) == null)
61
-                    {
62
-                        x = xx;
63
-                        y = yy;
64
-                        return;
65
-                    }
66
-                }
67
-            }
68
-            x = -1;
69
-            y = -1;
70
-        }
71
-
72
-        protected IEnumerable<int> GetDomainValues(Board board)
73
-        {
74
-            return Enumerable.Range(0, board.Size);
75
-        }
76
-
77
-        protected bool IsConsistent(Board board, int x, int y)
78
-        {
79
-            return Constraints.All(constraint => constraint.Check(board, x, y));
80
-        }
81 58
     }
82 59
 }

+ 26
- 0
uqac-ia-sudoku-csp/Solver/NextValueChoosers/BasicValueChooser.cs View File

@@ -0,0 +1,26 @@
1
+using System.Collections.Generic;
2
+using uqac_ia_sudoku_csp.Interfaces;
3
+
4
+namespace uqac_ia_sudoku_csp.Solver.NextValueChoosers
5
+{
6
+    public class BasicValueChooser : INextValueChooser
7
+    {
8
+        public void SelectVariable(Board board, out int x, out int y, IList<IConstraint> constraints)
9
+        {
10
+            for (var xx = 0; xx < board.Size; ++xx)
11
+            {
12
+                for (var yy = 0; yy < board.Size; ++yy)
13
+                {
14
+                    if (board.GetNumber(xx, yy) == null)
15
+                    {
16
+                        x = xx;
17
+                        y = yy;
18
+                        return;
19
+                    }
20
+                }
21
+            }
22
+            x = -1;
23
+            y = -1;
24
+        }
25
+    }
26
+}

+ 50
- 0
uqac-ia-sudoku-csp/Solver/NextValueChoosers/MRVNextValueChooser.cs View File

@@ -0,0 +1,50 @@
1
+using System.Collections.Generic;
2
+using uqac_ia_sudoku_csp.Interfaces;
3
+
4
+namespace uqac_ia_sudoku_csp.Solver.NextValueChoosers
5
+{
6
+    public class MRVNextValueChooser : INextValueChooser
7
+    {
8
+        public void SelectVariable(Board board, out int x, out int y, IList<IConstraint> constraints)
9
+        {
10
+            var avail = 1;
11
+            while (avail < board.Size)
12
+            {
13
+                for (var xx = 0; xx < board.Size; ++xx)
14
+                {
15
+                    for (var yy = 0; yy < board.Size; ++yy)
16
+                    {
17
+                        if (board.GetNumber(xx, yy) == null)
18
+                        {
19
+                            var remaining = GetRemainingValue(board, xx, yy, constraints);
20
+                            if (remaining == avail)
21
+                            {
22
+                                x = xx;
23
+                                y = yy;
24
+                                return;
25
+                            }
26
+                        }
27
+                    }
28
+                }
29
+                ++avail;
30
+            }
31
+            x = -1;
32
+            y = -1;
33
+        }
34
+
35
+        protected int GetRemainingValue(Board board, int x, int y, IList<IConstraint> constraints)
36
+        {
37
+            var c = 0;
38
+            for (var i = 0; i < board.Size; ++i)
39
+            {
40
+                board.SetNumber(x, y, i);
41
+                if (board.IsConsistent(x, y, constraints))
42
+                {
43
+                    ++c;
44
+                }
45
+            }
46
+            board.ClearNumber(x, y);
47
+            return c;
48
+        }
49
+    }
50
+}

Loading…
Cancel
Save