C# 数独解算器不工作

C# 数独解算器不工作,c#,algorithm,sudoku,C#,Algorithm,Sudoku,我想先创建一个数独解算器 计算可以放在正方形中的可能值 然后使用这些约束来回溯 使用系统; 使用System.Collections.Generic; 使用System.Linq; 使用系统文本; 使用System.Threading.Tasks; 命名空间数独解算器 { 静态类程序 { 私有静态整数[,]网格=新整数[,]{ { 3, 0, 6, 5, 0, 8, 4, 0, 0 }, { 5, 2, 0, 0, 0, 0, 0, 0, 0 }, { 0, 8, 7, 0, 0, 0, 0,

我想先创建一个数独解算器

  • 计算可以放在正方形中的可能值
  • 然后使用这些约束来回溯
  • 使用系统;
    使用System.Collections.Generic;
    使用System.Linq;
    使用系统文本;
    使用System.Threading.Tasks;
    命名空间数独解算器
    {
    静态类程序
    {
    私有静态整数[,]网格=新整数[,]{
    { 3, 0, 6, 5, 0, 8, 4, 0, 0 },
    { 5, 2, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 8, 7, 0, 0, 0, 0, 3, 1 },
    { 0, 0, 3, 0, 1, 0, 0, 8, 0 },
    { 9, 0, 0, 8, 6, 3, 0, 0, 5 },
    { 0, 5, 0, 0, 9, 0, 0, 6, 0 },
    { 1, 3, 0, 0, 0, 0, 2, 5, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 7, 4 },
    { 0, 0, 5, 2, 0, 6, 3, 0, 0 }
    };
    私有静态列表[,]约束;
    静态void Main(字符串[]参数)
    {
    GetConstraints();
    SolveSudokuGrid();
    PrintGrid();
    Console.Read();
    }
    静态布尔解算sudokugrid()
    {
    int行=-1,列=-1;
    if(IsGameOver(参考行,参考列)=true)
    返回true;
    //受到约束
    列表约束=约束[行,列];
    for(int i=0;i对于(int i=1;i当您想要假设一个数字是正确的时,您必须重新检查是否有重复的数字。如果该数字是在之前添加的,并且存在于当前列、行或框中,则转到下一个约束

    你们得到的答案是错误的,因为你们并没有在把数字放到表中之前重新检查

    所以,在将数字放入表中之前,您可以简单地使用自己的方法再次修复它

    您的for循环in
    SolveSudokuGrid
    方法如下

            for (int i = 0; i < constraint.Count; i++)
            {
                //Assume correct number by adding a constraint
                // But lets do a check if we already added in current column or row or box.
                if (usedInRow(row, constraint[i])) continue;
                if(usedInCol(col, constraint[i])) continue;
    
                int startRow = (row / 3) * 3;
                int startCol = (col / 3) * 3;
                if (usedInBox(startRow, startCol, constraint[i])) continue;
    
                grid[row, col] = constraint[i];
    
                if (SolveSudokuGrid() == true)
                    return true;
    
                //Cant solve. Backtrack
                grid[row, col] = 0;
            }
    
        static bool IsGameOver(ref int row, ref int col)
        {
            for (int r = 0; r < 9; r++)
            {
                for (int c = 0; c < 9; c++)
                {
                    if (grid[r, c] == 0)
                    {
                        // set the row and col.
                        row = r;
                        col = c;
    
                        // but Lets check for the element with least possibilities in constraints.
                        // and prefer it against current row and col
                        int min = constraints[r, c].Count;
                        for (int i = 0; i < 9; i++)
                        {
                            for (int j = 0; j < 9; j++)
                            {
                                if (constraints[i, j] != null && // if the constraint is available
                                    constraints[i, j].Count < min && // if found less possibilities
                                    grid[i, j] == 0) // if the element of the table is 0 (its not assigned yet)
                                {
                                    // set the row and col with less possibilities
                                    row = i;
                                    col = j;
    
                                    min = constraints[i, j].Count;
                                }
                            }
                        }
    
                        return false;
                    }
                }
            }
    
            return true;
        }
    
    然而,有时您可能会因为错误的表和算法设计而陷入无限循环(如果您输入了重复的数字)。但是,如果表本身不包含重复的数字,那么它应该可以正常工作

    更新:为了加速算法,而不是按顺序分配数字,您必须将数字分配给不太可能正确的元素

    这将大大提高算法的速度。这也是求解数独的常用方法

    您的
    IsGameOver
    方法如下

            for (int i = 0; i < constraint.Count; i++)
            {
                //Assume correct number by adding a constraint
                // But lets do a check if we already added in current column or row or box.
                if (usedInRow(row, constraint[i])) continue;
                if(usedInCol(col, constraint[i])) continue;
    
                int startRow = (row / 3) * 3;
                int startCol = (col / 3) * 3;
                if (usedInBox(startRow, startCol, constraint[i])) continue;
    
                grid[row, col] = constraint[i];
    
                if (SolveSudokuGrid() == true)
                    return true;
    
                //Cant solve. Backtrack
                grid[row, col] = 0;
            }
    
        static bool IsGameOver(ref int row, ref int col)
        {
            for (int r = 0; r < 9; r++)
            {
                for (int c = 0; c < 9; c++)
                {
                    if (grid[r, c] == 0)
                    {
                        // set the row and col.
                        row = r;
                        col = c;
    
                        // but Lets check for the element with least possibilities in constraints.
                        // and prefer it against current row and col
                        int min = constraints[r, c].Count;
                        for (int i = 0; i < 9; i++)
                        {
                            for (int j = 0; j < 9; j++)
                            {
                                if (constraints[i, j] != null && // if the constraint is available
                                    constraints[i, j].Count < min && // if found less possibilities
                                    grid[i, j] == 0) // if the element of the table is 0 (its not assigned yet)
                                {
                                    // set the row and col with less possibilities
                                    row = i;
                                    col = j;
    
                                    min = constraints[i, j].Count;
                                }
                            }
                        }
    
                        return false;
                    }
                }
            }
    
            return true;
        }
    
    static bool IsGameOver(参考整数行,参考整数列)
    {
    for(int r=0;r<9;r++)
    {
    对于(int c=0;c<9;c++)
    {
    if(网格[r,c]==0)
    {
    //设置行和列。
    row=r;
    col=c;
    //但是让我们检查约束中可能性最小的元素。
    //与当前行和列相比,更喜欢它
    int min=约束[r,c]。计数;
    对于(int i=0;i<9;i++)
    {
    对于(int j=0;j<9;j++)
    {
    如果(约束[i,j]!=null&&//如果约束可用
    约束[i,j]。如果发现可能性较小,则计数
    那么实际的问题是什么呢?你所做的只是说你有问题,但没有提到问题是什么。每次你假设一个数字是正确的,你都必须检查重复的数字。在输入之前,你必须检查之前是否加了相同的值。目前你没有检查。我认为这就是问题所在。
    grid[行,列]=约束[i];
    。这可能会导致同一行或同一列中出现重复。您好,它成功了!但需要80秒才能解决。这正常吗?我的首相的代码需要0.6秒才能解决。我不知道他在使用什么算法。此外,我不知道如何解决数独问题。我的意思是,我以前从未尝试过。我只是看了一下您的代码,以了解您使用的算法顺便说一句,我认为80秒是正常的,因为有很多可能会出错,值必须为b