【问题标题】:Sudoku logic solver数独逻辑解算器
【发布时间】:2014-08-14 03:37:30
【问题描述】:

由于缺乏信息,我的上一个问题here 被锁定,我现在将尝试进一步解释以消除混淆。

好的,请先了解一下我在做什么的背景信息。
我开始了一个制作数独游戏的个人项目,以学习面向对象编程、ArrayList、算法、模型/控制/设计层,并总体扩展我的编程知识。
我在制作这款游戏​​方面已经走了很长一段路,它已接近完成,但我遇到了一个需要帮助解决的小问题。

我在生成 3 个数独时遇到了问题,一个简单的,一个中等的,一个困难的。
简单和中等难度的数独是可以解的,但难的数独是无法解的。

它是如何工作的:
首先,我有一个使用随机数生成和验证的算法来生成一个有效的数独板,然后我将它传递给另一个算法,该算法遍历 9x9 板上的所有数字并以百分比的机会删除它们,这个百分比机会在调用时指定方法,例如 50% 的机会删除一个数字很容易和 65% 的机会很难。

我的问题:
好的,所以我的问题是我在“困难”难度下生成了一个数独,但发现它无法解决。现在我没有验证方法来检查这个谜题是否可以以任何方式解决,所以长话短说它是否可以解决是偶然的。

我需要什么:
我需要一个算法或方法来验证这个谜题是否是可解决的,因为现在我只有一个随机的机会可以解决它,因为随机数删除的机会。这不应该使用蛮力(回溯)来完成,而是应该看看这个谜题并决定哪些数字去哪里,基本上就像你我会解决它一样。这样我不仅可以验证它是否有一个解决方案,还可以验证你和我是否可以解决它。

变量的小图形视图以及类的连接方式:

使用上述示例对数独的结构进行直观表示:

数独中的 1 到 9 数字是单元格 1 到 9。

如果您需要有关该计划的更多详细信息,请告诉我,我会将其添加到此表单中,我只是尽量保持简短,同时仍试图涵盖与此问题相关的所有内容。

【问题讨论】:

  • 请注意,通常您应该编辑上一个问题,而不是就同一件事提出新问题...此外,您应该使您的问题更清楚。它隐藏在事物的中间,有点容易错过。
  • 我认为,如果一个数独谜题作为一种解决方案,我不认为这意味着获得的解决方案是唯一的解决方案。因此,您对溶解度的测试可能不够充分。如果我错了,请纠正我。
  • 你是说无法解决的仍然可以解决吗?如果是这样,你有一个算法错误。
  • @user3580294 我知道,但我认为这个问题无法挽救。
  • 在解决数独谜题时,我有时会使用铅笔和橡皮擦回溯的try and see further方法......不是只有一个人这样做!

标签: java algorithm sudoku


【解决方案1】:

如果您正在寻找解决数独的逻辑算法,那么这将很有帮助:

http://hodoku.sourceforge.net/en/techniques.php

http://diuf.unifr.ch/pai/people/juillera/Sudoku/Sudoku.html

【讨论】:

    【解决方案2】:

    我将尝试明确或隐含地回答您提出的问题:

    “首先我有一个算法使用随机数生成和验证来生成一个有效数独板”

    如果您的算法确实生成了一个有效数独板,那么它应该是可解的。如果这不是您所说的可解决的意思,请详细说明。

    “我需要一个算法或方法来验证这个谜题是否可以解决,因为现在我只有一个随机的机会可以解决它,因为随机数移除的机会。”

    任何解决数独的算法都将验证它确实是可解决的。删除任何数字实际上可能会使游戏更难解决,并且可能会增加有效解决方案的数量,从而使其无效(参见 Serge Ballesta 的巧妙评论)。我还想提一下:“数独谜题通常分为简单、中等或困难,谜题通常有更多的起始线索,但并不总是更容易解决。但用数学来量化难度很难。”。见Mathematics of Sudoku Leads To "Richter Scale" of Puzzle Hardness

    “这不应该使用蛮力(回溯)来完成,而是应该查看谜题并决定哪些数字去哪里,基本上就像你我会解决它一样。”

    您需要一种算法来模拟人类行为和思考来解决这个问题。我不认为这是一个可行的要求,可能会落入人工智能的研究领域。人类解决数独等谜题的思路因人而异。初学者可能会遵循类似于带有回溯的深度优先搜索的方法。在处理难题时,这对人类来说不是最有效的方法。在国际象棋等游戏中,这根本不是一种可持续的方法。专家倾向于通过对董事会的全球视野来识别模式。我很确定专家级数独人类玩家会遵循类似的过程。见How experts recall chess positions

    【讨论】:

    • 你错了一点:如果一个给定的数独谜题存在多个解,则该谜题被认为是“无效的”。
    • @SergeBallesta 根据您的评论更新了我的答案。
    • “如果你的算法确实生成了一个有效的数独板,那么它应该是可解的。如果这不是你所说的可解,请详细说明。”取出太多数字,玩家将无法解决。另一方面,蛮力总能找到解决方案,因为它会尝试所有可能的组合。
    • @Simon Jensen 从技术上讲,如果你取的数字太多,玩家仍然可以解决。在某些时候,玩家必须从给定的可能性中决定放什么数字,这可能是死胡同,如果是死胡同,那么玩家必须从该点回滚所有移动并尝试另一个数字。它是可以解决的,但不仅仅是“在这里只放一个可能的数字”那么简单。
    • @SimonJensen “取出太多数字,玩家将无法解决。”不正确,用户只需要放回已删除的号码。一般来说,如果给定的数独游戏是可解的,那么通过从任何位置移除任何数字而获得的任何游戏都是可解的,尽管它可能不再是有效的数独,因为可能引入了更多有效的解决方案,而有效的游戏需要独特的解决方案。
    【解决方案3】:

    我赞同Tarik 在他的回答中所说的话。

    我能想到的可能算法(只是想法,不是最优但可以改进):

    第一部分 - 直接解决:

    • 1) 为每个空单元格分配要插入的可能数字列表(基于数独规则)。
    • 2) 遍历每个空单元格并检查要插入的可能数字列表是否仅包含一个元素。

    如果只包含一个可能要插入的数字,则插入该数字并重复步骤 (1)。 如果您无法插入更多数字,请转到第二部分。

    第二部分 - 分支:

    • 3) 根据要插入的可能数字的数量(从第一部分开始),按升序遍历每个空单元格。
    • 4) 递归来了。对于要填写给定单元格的每个可能数字,创建单独的数独板并尝试从步骤(1)开始以相同的方式解决它

    这种递归方法(深度优先搜索)将允许您找到所有可能的解决方案。

    这是提高编程技能的好练习:)

    【讨论】:

    • 你知道有什么例子可以做到这一点吗?
    【解决方案4】:

    你要做的第一部分是非程序化的:你必须找到一个详尽的(到一定程度......)解决方法的列表。然后依次应用它们,直到您解决难题并声明它可由您的程序解决,或者继续卡住并决定拒绝它。

    但这还不够。如果您能找到解决方案,您仍然需要通过蛮力验证该解决方案是唯一的。如果不这样做,您可能会生成具有多个解决方案的谜题,并且大多数玩家都宣布这些解决方案无效。

    拒绝无法通过您的方法解决的有效谜题不太重要,因为没有人会注意到它们(只要您不让用户输入他们自己的谜题)。

    【讨论】:

    • 只要求解方法正确(单元格内容只有在可以唯一确定的情况下才确定),只有一种可能的解决方案。
    • “你必须找到一个详尽的(到一定程度......)解决方法列表。”一种解决方法应该可以。以编程方式求解数独相对来说是微不足道的。您可以使用通常提供数独作为玩具问题示例的约束编程库。
    猜你喜欢
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    相关资源
    最近更新 更多