Просмотр исходного кода

changed to a while loop instead of weird recursion, and abstracted the fetching of the next value to attempt. also check for invalid domains after inferring

Tareef 6 лет назад
Родитель
Сommit
7b33388e74
1 измененных файлов с 41 добавлено и 22 удалено
  1. 41 22
      a1/sudoku.py

+ 41 - 22
a1/sudoku.py

@@ -210,20 +210,19 @@ def lcv(solutions, index, val):
                 ++count
                 
     return count
-
-# recursive solver that uses heuristics to decide what node to explore
-def solveh(working, domains, unassigned):
-    if (not unassigned):
-        return working
     
-    # heap and superheap used to record indices that are the "best" according to the heuristics
+    
+# return the correct node + val to try
+def genVal(domains, working, unassigned):
     heap = []
     superheap = []
     bestrating = 1.0
     
     # get the best indices according to domain size
     for i in unassigned:
-        rating = domsize(domains, i) / 9
+        rating = domsize(domains, i) / 9.0
+        if (rating == 0):
+            print(i)
         if (rating < bestrating):
             bestrating = rating
             heap = [i]
@@ -233,7 +232,7 @@ def solveh(working, domains, unassigned):
     # get the best indices according to degree(related cells)
     bestrating = 1
     for i in heap:
-        rating = related(working, i) / 27
+        rating = related(working, i) / 27.0
         if (rating < bestrating):
             bestrating = rating
             superheap = [i]
@@ -242,7 +241,7 @@ def solveh(working, domains, unassigned):
     
     index = superheap[0]
     bestrating = 27
-    val = 0
+    val = working[index[0]][index[1]]
     
     # get best values according to LCV
     for i in domains[index[0]][index[1]]:
@@ -250,23 +249,43 @@ def solveh(working, domains, unassigned):
         if (rating <= bestrating):
             bestrating = rating
             val = i
+            
+    return (index, val)
+
+
+# recursive solver that uses heuristics to decide what node to explore
+def solveh(working, domains, unassigned):
+    if (not unassigned):
+        return working
+    
+    while(unassigned):
+        nextThing = genVal(domains, working, unassigned)
+        index = nextThing[0]
+        val = nextThing[1]
 
-    working[index[0]][index[1]] = val
-    unassigned.remove(index)
+        working[index[0]][index[1]] = val
+        unassigned.remove(index)
+        if (index == (8, 8)):
+            print("value is: ", val)
     
-    newdomains = infer(copy.deepcopy(domains), copy.deepcopy(working), index[0], index[1], val)
-    result = solveh(copy.deepcopy(working), copy.deepcopy(newdomains), copy.deepcopy(unassigned))
-    if (result):
-        return result
-    elif (domains[index[0]][index[1]]):
-        working[index[0]][index[1]] = 0
-        domains[index[0]][index[1]].remove(val)
-        unassigned.append(index)
-        result = solveh(copy.deepcopy(working), copy.deepcopy(domains), copy.deepcopy(unassigned))
+        # check for invalidated nodes (empty domain)
+        flag = True
+        result = False
+        newdomains = infer(domains, working, index[0], index[1], val)
+        for i in range(0, 9):
+            for j in range(0, 9):
+                if (not domains[i][j]):
+                    flag = False
+        
+        if (flag): result = solveh(working, newdomains, copy.deepcopy(unassigned))
         if (result):
             return result
-    
-    return False
+        elif (len(domains[index[0]][index[1]]) > 1):
+            working[index[0]][index[1]] = 0
+            domains[index[0]][index[1]].remove(val)
+            unassigned.append(index)
+        else:
+            return False
 
 
 # forward checking solver with heuristics