我已经创建了一个用于解决数独谜题的回溯算法,它基本上分别从左到右,自上而下遍历所有空白字段。现在我需要制作一个扩展版本,其中算法遍历字段的顺序由每个字段的可能性(在初始化时计算一次)定义。例如。应首先访问最初具有最少量可能值的空字段,并且仅应检查最初可能的值(两者都是为了减少所需的迭代量)。现在我不确定如何在不增加为每个字段实际定义这些值所需的迭代量的情况下继续实现它,然后以最少的可能性获得下一个字段。
对于我的回溯算法,我有一个nextPosition方法,它确定要访问的数独中的下一个空字段。现在它看起来像这样:
protected virtual int[] nextPosition(int[] position)
{
int[] nextPosition = new int[2];
if (position[1] == (n * n) - 1)
{
nextPosition[0] = position[0]+1;
nextPosition[1] = 0;
}
else
{
nextPosition[0] = position[0];
nextPosition[1] = position[1]+1;
}
return nextPosition;
}
所以它基本上分别穿过数独左右,自上而下。现在我需要为我的新版本改变这个以遍历按字段的最少量可能值排序的字段(并且仅在我的回溯算法中尝试每个字段的可能值)。我想我会尝试为每个字段保留一个无效值列表:
public void getInvalidValues(int x, int y)
{
for (int i = 0; i < n * n; i++)
if (grid[y, i] != 0)
this.invalidValues[y, i].Add(grid[y, i]);
for (int i = 0; i < n * n; i++)
if (grid[i, x] == 0)
this.invalidValues[i, x].Add(grid[i, x]);
int nX = (int)Math.Floor((double)x / n);
int nY = (int)Math.Floor((double)y / n);
for (int x = 0; x < n; x++)
for (int y = 0; y < n; y++)
if (grid[nY * n + y, nX * n + x] != 0)
this.invalidValues[y, x].Add(grid[y, x]);
}
为sudoku中的每个空字段调用此方法(在this.grid中表示为2D数组[n n,n n])。然而,这会导致更多的迭代,因为为了确定每个字段的不同无效值的数量,它必须再次遍历每个列表。
所以我的问题是,是否有人知道如何通过每个字段的可能值的数量有效地遍历数独的字段(同时跟踪每个字段的这些可能值,因为它们是需要的回溯算法)。如果有人能帮助我,我会非常感激。
提前致谢!