无法回溯以使用递归 javascript 数独求解器
Posted
技术标签:
【中文标题】无法回溯以使用递归 javascript 数独求解器【英文标题】:Can't get backtrack to work on recursive javascript sudoku sovler 【发布时间】:2021-08-12 18:18:01 【问题描述】:我绞尽脑汁,但看不出哪里出了问题,从控制台日志看来,回溯无法正常工作是个问题,我认为这与我的方式有关正在使用位置对象,我们将不胜感激,
它一直有效,直到回溯应该起作用,我可以看到它确实回溯了 6 次,但该位置实际上并没有返回并改变以前的数字
let grid = [];
const solve = function (pos)
while (pos.x < 9 && pos.y < 9 && grid[pos.x][pos.y].value)
pos = incrementPos(pos);
// skip non-empty cells
if (pos.y == 9) return true;
for (let m = 1; m < 10; m++)
grid[pos.x][pos.y].value = m;
console.log(pos, m);
if (isValid(m, pos))
if (solve(incrementPos(pos)))
return true;
console.log("start backtrack", pos);
grid[pos.x][pos.y].value = "";
return false;
;
function isValid(n, pos)
let valid = true;
let row = checkRow(n, pos);
let col = checkCol(n, pos);
let block = checkBlock(n, pos);
if (!row || !col || !block)
return false;
else
return true;
function checkBlock(n, pos)
let startX = parseInt(pos.x / 3) * 3;
let startY = parseInt(pos.y / 3) * 3;
for (let x = startX; x < startX + 3; x++)
for (let y = startY; y < startY + 3; y++)
if ((grid[x][y].value === n) & (x !== pos.x) & (y !== pos.y))
return false;
return true;
function checkRow(n, pos)
for (let t = 0; t < 9; t++)
if (grid[t][pos.y].value === n && t !== pos.x)
return false;
return true;
function checkCol(n, pos)
for (let t = 0; t < 9; t++)
if ((grid[pos.x][t].value === n) & (t !== pos.y))
return false;
return true;
function incrementPos(pos)
if (pos.x < 8)
pos.x++;
else
pos.y++;
pos.x = 0;
return pos;
const initGrid = function ()
for (let x = 0; x < 9; x++)
let col = [];
for (let y = 0; y < 9; y++)
let el = ;
el.locked = false;
el.value = "";
el.location = document.querySelector("#r" + (y + 1) + "c" + (x + 1));
col.push(el);
grid.push(col);
displayGrid();
;
const displayGrid = function ()
for (let x = 1; x < 10; x++)
for (let y = 1; y < 10; y++)
document.querySelector("#r" + y + "c" + x).textContent =
grid[x - 1][y - 1].value;
;
【问题讨论】:
没有简单的方法来运行这段代码,而且它太复杂以至于无法看清。也许您可以使用所需的 html/CSS 创建一个工作代码 sn-p,其中包括一个显示问题的示例数独。 嗨詹姆斯,我确定我已经在 JSFiddle 上创建了:jsfiddle.net/87qnoyum/1 【参考方案1】:我真的不知道你在做什么,这太多了,但是我看不出你实际上在哪里重置位置。我正在寻找这样的东西:
const getBlock = (block) =>
if (block === 9)
return true
// you can use a total variable here to try it a couple of times before backtracking
const valid = false
...
if (valid)
getBlock(++block)
else
getBlock(--block)
该代码根本不完美,但它只是为了向您展示这个想法,如果它有效,您应该增加块,并且经过几次迭代之后您找不到另一个块,您应该重置块返回上一个并重试。回溯的结果是,如果您在控制台记录块,您应该会看到如下内容: 1 -> 2 -> 3 -> 4 -> 3 -> 4 -> 5 -> 4 -> 3 -> 4 -> 5 - > 6 -> ... 来来回回,直到最终找到解决方案。
在您自己的代码中,我希望它是这样的:
if (solve(incrementPos(pos)))
return true
else
solve(decrementPos(pos)) // or something
// otherwise you're not actually backtracking
旁注,您可以使用模算术而不是循环。如果您知道自己处于特定块中,则可以立即验证/无效并检查值是否存在于相关行/列/对角线中而没有任何循环。只是一个提示。
【讨论】:
谢谢!你是对的,我所要做的就是在返回 false 之前添加一个递减 pos 并且这解决了它。我是 *** 的新手,但我会尽快弄清楚如何选择这是正确的答案,再次感谢您 更新:“工作”原来还为时过早,不幸的是更新后的代码现在改变了预设元素,它回到了绘图板以上是关于无法回溯以使用递归 javascript 数独求解器的主要内容,如果未能解决你的问题,请参考以下文章