Recursion 在maple中解决4X4数独问题

Recursion 在maple中解决4X4数独问题,recursion,sudoku,backtracking,maple,Recursion,Sudoku,Backtracking,Maple,所以我尝试使用递归和回溯来解决4x4数独。 当我称之为数独(L); “现在解决…” 它给了我这个“错误,(在数独中)矩阵索引超出范围” 但是我不能发现任何与我的矩阵L有关的bug。我的程序似乎没有正确地执行回溯部分。我认为我的findPossibleEntries程序运行良好。它确实找到了特定单元格的所有可能值。有人得到任何提示吗 > L := Matrix(4,4,[ [0,4,0,0],[2,0,0,3],[4,0,0,1],[0,0,3,0] ]); > isFull :=

所以我尝试使用递归和回溯来解决4x4数独。 当我称之为数独(L); “现在解决…” 它给了我这个“错误,(在数独中)矩阵索引超出范围” 但是我不能发现任何与我的矩阵L有关的bug。我的程序似乎没有正确地执行回溯部分。我认为我的findPossibleEntries程序运行良好。它确实找到了特定单元格的所有可能值。有人得到任何提示吗

> L := Matrix(4,4,[ [0,4,0,0],[2,0,0,3],[4,0,0,1],[0,0,3,0] ]);
 > isFull := proc(L)
    local x, y;    
        for x from 1 to 4 do
        for y from 1 to 4 do
         if L[x,y]=0 then
                 return false;
              end if;
           end do;
        end do;

        return true;
        end proc;

>findPossibleEntries := proc(L, i, j)
    local x, y, possible:=[0,0,0,0];
    local r:=1, c:=1;


#Checking possible entries in ith row
for y from 1 to 4 do
    if not L[i,y] = 0 then
       possible[L[i,y]] := 1;     
    end if;
end do;

#Checking possible entries in jth col
for x from 1 to 4 do
    if not L[x,j] = 0 then
       possible[L[x,j]] := 1;

    end if;
end do;

#Checking possible entries block by block
if i >= 1 and i <= 2 then
   r := 1;
elif i >= 3 and i <= 4 then
   r := 3;
end if;

if j >= 1 and j <= 2 then
   c := 1;
elif j >= 3 and j <= 4 then
   c := 3;
end if;

#Using for-loop to find possible entries in the block
for x in range(r, r+1) do
      for y in range(c, c+1) do

            if not L[x,y] = 0 then
               possible[L[x,y]] := 1;
            end if;
      end do;
end do;


#Now the list, possible, only holds the possible entries
for x from 1 to 4 do
    if possible[x] = 0 then
       possible[x] := x;
    else
       possible[x] := 0;
    end if;
end do;

return possible;

end proc;

>SolveSmallSudoku := proc(L)
local x, y, i:=0, j:=0, possibleVal:=[0,0,0,0];

if isFull(L) then
   print("Solved!");
   print(L);
   return;
else
   print("Solving now...");

   for x from 1 to 4 do
       for y from 1 to 4 do
          if L[x,y] = 0 then
               i:=x;
               j:=y;
               break;
          end if
       end do;
       #Breaks the outer loop as well
       if L[x,y] = 0 then
          break;
       end if

   end do;    

#Finds all the possibilities for i,j
possibleVal := findPossibleEntries(L,i,j);

#Traverses the list, possibleVal to find the correct entries and finishes the sudoku recursively 
for x from 1 to 4 do
    if not possibleVal[x] = 0 then
       L[i,j]:= possibleVal[x];
       SolveSmallSudoku(L);
    end if;
end do;
#Backtracking
 L[i,j]:= 0;

end if;


end proc;
>L:=矩阵(4,4,[[0,4,0,0],[2,0,0,3],[4,0,0,1],[0,0,3,0]);
>isFull:=proc(L)
局部x,y;
对于x,从1到4执行
对于y,从1到4执行
如果L[x,y]=0,则
返回false;
如果结束;
结束do;
结束do;
返回true;
结束进程;
>findPossibleEntries:=proc(L,i,j)
局部x,y,可能:=[0,0,0,0];
局部r=1,c=1;
#检查第i行中的可能条目
对于y,从1到4执行
如果不是L[i,y]=0,那么
可能的[L[i,y]]:=1;
如果结束;
结束do;
#检查jth col中可能的条目
对于x,从1到4执行
如果不是L[x,j]=0,那么
可能的[L[x,j]]:=1;
如果结束;
结束do;
#逐块检查可能的条目
如果i>=1且i=3且i=1且j=3且j=数独:=proc(L)
局部x,y,i:=0,j:=0,可能值:=[0,0,0,0];
如果已满(L),则
打印(“已解决!”);
印刷品(L);
返回;
其他的
打印(“立即解决…”);
对于x,从1到4执行
对于y,从1到4执行
如果L[x,y]=0,则
i:=x;
j:=y;
打破
如果结束
结束do;
#也打破了外部循环
如果L[x,y]=0,则
打破
如果结束
结束do;
#找到i,j的所有可能性
可能值:=找到可能的条目(L,i,j);
#遍历列表,找到正确的条目并递归完成数独
对于x,从1到4执行
如果不可能eval[x]=0,则
L[i,j]:=possibleVal[x];
数独(L);
如果结束;
结束do;
#回溯
L[i,j]:=0;
如果结束;
结束进程;
摆脱

#Breaks the outer loop as well
   if L[x,y] = 0 then
      break;
   end if
正如您最初看到的,外部检查试图访问给定示例L的L[1,5]

相反,将内部循环中的
中断
替换为

x:=4; break;
这将导致外循环也在下一次迭代中完成(这恰好发生在内循环结束或中断之后。因此,您将获得所需的完全中断


然后,代码似乎按照您的预期工作,并为您的输入示例打印解决方案。

您可以通过在调试器中运行自己看到它,或者通过
print(x,y)
在外部
之前,如果L[x,y]=0,然后我建议您删除它。请注意以下常见行为,当结束此循环时,
y的最终值为5:
y从1到4 do;end do:y;
。感谢您的澄清。您知道这种“常见行为”背后的想法吗,其中for循环中的条件是
y