C#数独求解器计算导致崩溃

Posted

技术标签:

【中文标题】C#数独求解器计算导致崩溃【英文标题】:C# Sudoku solver computation result in crash 【发布时间】:2015-06-03 13:26:01 【问题描述】:

好的,我用 c++ 编写了这种程序,并在一秒钟内编译并计算出合理的答案,没问题。 我试图将程序翻译成 c#,因为我想要带有文本框的漂亮图形界面,以及我可以在 Visual Studio 中使用 c# 获得的那种。算法很相似,但是c#版本不会在程序崩溃之前产生结果,我不知道为什么......

我的程序的更多信息: 我有一个包含 81 个 TextBox 对象的列表,初始数组使用 for 循环进行初始化,以便为二维数组中的正确位置提供正确的值。

然后将该数组传递给递归函数,并将该数组和行的引用以及 col = 0 作为参数(因为 c# 不会使用未签名的局部变量进行编译)。我已经调试了程序以检查是否为数组中的正确位置提供了正确的值,这没有问题。

另外使用 Visual Studio 中的调试器,我发现调试器使用大量时间来从递归函数的第一个函数调用到下一个函数调用。

快速挪威语指南:rad = row,kol = column。我希望不会有太大问题。

Main:(这是一个按钮事件触发器)

        private void btnLøs_Click(object sender, System.Windows.RoutedEventArgs e)
    
        int rad, kol;

        rad = 0; kol = 0;
        int[,] array = new int[9,9];

        for(int i = 0; i < 81;i++)
        
            int tmpRad = i / 9;
            int tmpKol = i % 9;
            //Celler is the list of textblocks that represents the grid
            if(celler[i].Text == "")
            

                array[tmpRad, tmpKol] = 0;
            

            else
                array[tmpRad,tmpKol] = Convert.ToInt32(celler[i].Text);
        

        LøsSodoku(ref array,rad,kol);

        for(int i = 0; i < 81;i++)
        
            int tmpRad = i / 9;
            int tmpKol = i % 9;

            array[tmpRad,tmpKol] = Convert.ToInt32(celler[i].Text);

            celler[i].Text = array[tmpRad,tmpKol].ToString();
        
    

代码:

private bool gridHarLedigPlass(ref int[,] arr, ref int rad, ref int kol)
 //check if the array has empty cells (cells with 0)    
    
        for (rad = 0; rad < 9; rad++)
        
            for (kol = 0; kol < 9; kol++)
            
                if (arr[rad, kol] == 0)
                
                    return true;
                
            
        
        return false;
    

    private bool tallIBox(ref int[,] arr, int startRad, int startKol, int num)
    
        int tmpRad = startRad, tmpKol = startKol;

        for (int rad = 0; rad < 3; rad++)
        
            for (int kol = 0; kol < 3; kol++)
            
                if (rad != tmpRad && kol != tmpKol)
                
                    if (arr[rad + startRad, kol + startKol] == num)
                    
                        return true;
                    
                
            
        
        return false;
    

    private bool tallIRad(ref int[,] arr, int rad, int kol, int num)
    //Check if the num exists in the row
    
        int tmpRad = rad, tmpKol = kol;

        for (kol = 0; kol < 9; kol++)
        
            if (rad != tmpRad && kol != tmpKol)
            
                if (arr[rad, kol] == num)
                
                    return true;
                
            
        
        return false;
    

    private bool tallIKolonne(ref int[,] arr, int rad, int kol, int num)
    //Check if the num exists in the column
    
        int tmpRad = rad, tmpKol = kol;
        for (rad = 0; rad < 9; rad++)
        
            if (rad != tmpRad && tmpKol != kol)
            
                if (arr[rad, kol] == num)
                
                    return true;
                
            
        
        return false;
    

    private bool erSafe(ref int[,] arr, int rad, int kol, int num)
    //Check if the placement is valid
    
        return !tallIRad(ref arr, rad, kol, num) && !tallIKolonne(ref arr, rad, kol, num)
            && !tallIBox(ref arr, rad - rad%3, kol - kol%3, num);
    

    private bool LøsSodoku(ref int[,] arr, int rad, int kol)
    //Recursive backtracking function
    

        //Check if all cells are filled with numbers
        if (!gridHarLedigPlass(ref arr, ref rad, ref kol))
        
            return true;
        

        for (int num = 1; num <= 9; num++)
        
            if (erSafe(ref arr, rad, kol, num))
            
                arr[rad, kol] = num;

                if (LøsSodoku(ref arr, rad, kol))
                
                    return true;
                

                arr[rad, kol] = 0;
            
        
        return false;
    

【问题讨论】:

你将什么作为参数传递给这些方法? 你说程序崩溃了——当它崩溃时你会得到什么信息?这可能有用。 好吧,我不知道该怎么称呼它。但是cpu使用率是天翻地覆,不管用多久都不会出结果。 您能否举一个您将使用的数组示例,以便我们测试您的方法? 据我所知,您不会在递归调用中更改 radkol - 因此您将一遍又一遍地重试同一个单元格(您不会先检查它是否也已经设置好了)-所以我猜你在调用if (LosSodoku(ref arr, rad, kol))之前错过了移动到下一个单元格-顺便说一句:为什么ref代表arr 【参考方案1】:

我找到了问题的根源,但是为什么程序会产生错误的结果,这让我很头疼。 显然,我必须做的是删除每个不同数独测试中的 tmpRad 和 tmpKol 检查以产生正确的结果。

现在它就像一个魅力。

【讨论】:

以上是关于C#数独求解器计算导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 数独求解器在某些板上陷入无限循环/不适用于所有板

计算属性设置器导致 vuejs / javascript 在日期选择器焦点上崩溃浏览器

为啥这个“数独求解器”算法不起作用

为啥这个数独求解器返回相同的板而不解决任何问题?

数独求解器回溯算法不起作用

python 数独求解器