Browse Source

added samples; added MRV strategy

master
Robin Thoni 7 years ago
parent
commit
ef16560093

+ 9
- 0
sample/00.txt View File

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

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
 using System;
1
 using System;
2
+using System.Collections.Generic;
2
 using System.IO;
3
 using System.IO;
3
 using System.Linq;
4
 using System.Linq;
5
+using uqac_ia_sudoku_csp.Interfaces;
4
 
6
 
5
 namespace uqac_ia_sudoku_csp
7
 namespace uqac_ia_sudoku_csp
6
 {
8
 {
93
             return !Game.Any(line => line.Any(cell => cell == null));
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
         public void Print(TextWriter stream)
103
         public void Print(TextWriter stream)
97
         {
104
         {
98
             stream.WriteLine(Characters);
105
             stream.WriteLine(Characters);

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

1
-namespace uqac_ia_sudoku_csp.Interfaces
1
+using System.Collections.Generic;
2
+
3
+namespace uqac_ia_sudoku_csp.Interfaces
2
 {
4
 {
3
     public interface INextValueChooser
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
 using System;
1
 using System;
2
 using uqac_ia_sudoku_csp.Solver;
2
 using uqac_ia_sudoku_csp.Solver;
3
 using uqac_ia_sudoku_csp.Solver.Generators;
3
 using uqac_ia_sudoku_csp.Solver.Generators;
4
+using uqac_ia_sudoku_csp.Solver.NextValueChoosers;
4
 
5
 
5
 namespace uqac_ia_sudoku_csp
6
 namespace uqac_ia_sudoku_csp
6
 {
7
 {
13
             var generator = new FileGenerator();
14
             var generator = new FileGenerator();
14
             generator.Generate(board, new FileGeneratorDbo
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
             board.Print(Console.Out);
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
             var resolved = solver.Resolve(board);
24
             var resolved = solver.Resolve(board);
25
+            var end = DateTime.Now;
23
 
26
 
24
             if (resolved.Success)
27
             if (resolved.Success)
25
             {
28
             {
31
                 Console.WriteLine("Not resolved");
34
                 Console.WriteLine("Not resolved");
32
             }
35
             }
33
             Console.WriteLine($"{resolved.TryCount} tries");
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
-using System;
2
-using System.Collections.Generic;
1
+using System.Collections.Generic;
3
 using System.Linq;
2
 using System.Linq;
4
 using uqac_ia_sudoku_csp.Interfaces;
3
 using uqac_ia_sudoku_csp.Interfaces;
5
 using uqac_ia_sudoku_csp.Solver.Constraints;
4
 using uqac_ia_sudoku_csp.Solver.Constraints;
8
 {
7
 {
9
     public class BacktrackSearch : ISolver
8
     public class BacktrackSearch : ISolver
10
     {
9
     {
10
+        private readonly INextValueChooser _nextValueChooser;
11
         protected IList<IConstraint> Constraints;
11
         protected IList<IConstraint> Constraints;
12
 
12
 
13
-        public BacktrackSearch()
13
+        public BacktrackSearch(INextValueChooser nextValueChooser)
14
         {
14
         {
15
+            _nextValueChooser = nextValueChooser;
15
             Constraints = new List<IConstraint>
16
             Constraints = new List<IConstraint>
16
             {
17
             {
17
                 new LineContraint(),
18
                 new LineContraint(),
22
 
23
 
23
         public SolverResult Resolve(Board board)
24
         public SolverResult Resolve(Board board)
24
         {
25
         {
26
+            var domain = Enumerable.Range(0, board.Size).ToList();
25
             var result = new SolverResult();
27
             var result = new SolverResult();
26
-            result.Success = RecursiveResolve(board, result);
28
+            result.Success = RecursiveResolve(board, result, domain);
27
             return result;
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
             if (board.IsComplete())
34
             if (board.IsComplete())
33
             {
35
             {
34
                 return true;
36
                 return true;
35
             }
37
             }
36
             int x, y;
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
             return false;
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

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

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