1. 程式人生 > >Java回溯演算法解數獨問題

Java回溯演算法解數獨問題

    下面來詳細講一下如何用回溯演算法來解數獨問題。

    下圖是一個數獨題,也是號稱世界上最難的數獨。當然了,對於計算機程式來說,只要演算法是對的,難不難就不知道了,反正計算機又不累。回溯演算法基本上就是窮舉,解這種數獨類的問題邏輯比較簡單。


不管演算法懂不懂,先把類建出來,變數定義好,那放大學試卷上就是可以拿兩分了。

[java]  view plain  copy   在CODE上檢視程式碼片
派生到我的程式碼片
  1. package shudu;  
  2.   
  3. /** 
  4.  * Created by wolf on 2016/3/17. 
  5.  */  
  6. public class Sudoku {  
  7.     private int[][] matrix;  
  8.     public Sudoku(int[][] matrix) {  
  9.         this.matrix = matrix;  
  10.     }  
  11.   
  12.     public static 
    void main(String[] args) {  
  13.         // 號稱世界上最難數獨  
  14.         int[][] sudoku = {  
  15.                 {800000000},  
  16.                 {003600000},  
  17.                 {070090200},  
  18.                 {050007000},  
  19.                 {000045700},  
  20.                 {000100030},  
  21.                 {001000068},  
  22.                 {008500010},  
  23.                 {090000400}};  
  24.         Sudoku s = new Sudoku(sudoku);  
  25.         s.backTrace(00);  
  26.     }  
  27.   
  28.     /** 
  29.      * 數獨演算法 
  30.      * @param i 
  31.      * 行號 
  32.      * @param j 
  33.      * 列號 
  34.      */  
  35.     private void backTrace(int i, int j) {  
  36.   
  37.     }  
  38. }  

    用一個二維陣列來儲存這個矩陣,然後定義一個方法來計算。方法裡有兩個屬性——行號和列號。

    我們的原理就是從第0行0列開始,依次往裡面填入1-9之間的數字,然後判斷填入的這個數字是否能放進去(該行該列和它所在的小九宮格是否有重複數字)。如果能放進去,那麼就繼續用1-9去試該行的下一列。一直到該行的最後一列,然後換行繼續重複上面的步驟(也就是執行backTrace方法)。一直執行到最後一個空格,也就是i=8,j=8的時候,且最後這個空格所放的值也完全符合規則,那麼此時就算完成,不用再繼續呼叫backTrace方法了,輸出正確解即可。

   

所以回溯法樣子看起來是這樣的。給第一個空格填1-9中任何一個,開始判斷,如果OK,然後進入下一層,如果不OK,就斷掉了。下一層還是從1-9開始試,然後OK,不OK……當最終目標達到時,空格已填滿又滿足條件,那麼中斷該分支,輸出結果。

    繼續我們的程式。

    由於有些位置已經有數字了,所以我們需要判斷,如果該坑已經有人蹲了,那麼就把列號j加1,進入下一列。如果到第8列了,就換行。

    修改程式如下:

[java]  view plain  copy   在CODE上檢視程式碼片 派生到我的程式碼片
  1. package shudu;  
  2.   
  3. /** 
  4.  * Created by wolf on 2016/3/17. 
  5.  */  
  6. public class Sudoku {  
  7.     private int[][] matrix;  
  8.   
  9.     public Sudoku(int[][] matrix) {  
  10.         this.matrix = matrix;  
  11.     }  
  12.   
  13.     public static void main(String[] args) {  
  14.         // 號稱世界上最難數獨  
  15.         int[][] sudoku = {  
  16.                 {800000000},  
  17.                 {003600000},  
  18.                 {070090200},  
  19.                 {050007000},  
  20.                 {000045700},  
  21.                 {000100030},  
  22.                 {001000068},  
  23.                 {008500010},  
  24.                 {090000400}};  
  25.         Sudoku s = new Sudoku(sudoku);  
  26.         s.backTrace(00);  
  27.     }  
  28.   
  29.     /** 
  30.      * 數獨演算法 
  31.      * 
  32.      * @param i 行號 
  33.      * @param j 列號 
  34.      */  
  35.     private void backTrace(int i, int j) {  
  36.         //如果i行j列是空格,那麼才進入給空格填值的邏輯  
  37.         

    相關推薦

    Java回溯演算法解數問題

        下面來詳細講一下如何用回溯演算法來解數獨問題。     下圖是一個數獨題,也是號稱世界上最難的數獨。當然了,對於計算機程式來說,只要演算法是對的,難不難就不知道了,反正計算機又不累。回溯演算法基本上就是窮舉,解這種數獨類的問題邏輯比較簡

    回溯演算法解數問題(java版)

        下面來詳細講一下如何用回溯演算法來解數獨問題。     下圖是一個數獨題,也是號稱世界上最難的數獨。當然了,對於計算機程式來說,只要演算法是對的,難不難就不知道了,反正計算機又不累。回溯演算法基本上就是窮舉,解這種數獨類的問題邏輯比較簡單。 不管演算法懂不懂,先把

    [人工智慧]回溯演算法解數

    今天在AI課上學了CSP,然後學了回溯演算法。所以就用回溯演算法來解數獨吧。 數獨問題可以把九九八十一個格簡化為81個變數,每一個變數可以取1-9的值,當然,一開始初始化的值是不可以改變的。然後呢,對於這個數獨呢,有3個約束條件:(1)每行數字不能重複;(2)每列數字不能重

    演算法之6-回溯解數問題

     剛開始學習的時候,總是不知道對陣列進行回溯的時候,怎麼保證找到的是下一個空值, 所以寫好一半的程式碼就放在一邊,一個星期之後回過頭再看回溯法解數獨的時候,突然醒悟過來: 原來在構造陣列的時候,以0值代替空值,當從1-9的某一個數填入該處的時候,該處就不是0值,回溯重新呼叫

    演算法分析】回溯解數(九宮格)演算法

    這篇文章,是來詳細介紹怎樣寫出一個演算法,來解出所有的數獨問題。演算法的程式執行時間,縮減在了毫秒級別。等到這篇文章結束,我會抽時間寫一篇文章,介紹如何生成一個隨機的唯一解的數獨問題。 另外,為了做圖形方便,示範程式碼是用C++,喜歡其他語言的朋

    LeetCode37 使用回溯演算法實現解數,詳解剪枝優化

    本文始發於個人公眾號:**TechFlow**,原創不易,求個關注 數獨是一個老少咸宜的益智遊戲,一直有很多擁躉。但是有沒有想過,數獨遊戲是怎麼創造出來的呢?當然我們可以每一關都人工設定,但是顯然這工作量非常大,滿足不了數獨愛好者的需求。 所以常見的一種形式是,我們只會選擇難度,不同的難度對應不同的留空

    Leetcode演算法——37、求解數

    編寫程式,來求解一個數獨問題。 一個數獨的答案必須滿足以下規則: 1-9的每個數字都必須在每一行中都只出現一次 1-9的每個數字都必須在每一列中都只出現一次 1-9的每個數字都必須在每一個3*3的小方塊中都只出現一次 空格子用.表示。 思路

    0-1揹包問題—回溯演算法java實現

    0-1揹包問題 【問題描述】 有n種可選物品1,…,n ,放入容量為c的揹包內,使裝入的物品具有最大效益。 表示 n :物品個數 c :揹包容量 p1,p2, …, pn:個體物品效益值 w1,w2, …,wn:個體物品容量 【問題解析】 0-1揹包問題的解指:物品1,…,n的一種放

    8皇后以及N皇后演算法探究,回溯演算法JAVA實現,非遞迴,迴圈控制及其優化

    研究了遞迴方法實現回溯,解決N皇后問題,下面我們來探討一下非遞迴方案 實驗結果令人還是有些失望,原來非遞迴方案的效能並不比遞迴方案效能高 程式碼如下: package com.newflypig.eightqueen; import java.util.Date; /**

    8皇后以及N皇后演算法探究,回溯演算法JAVA實現,非遞迴,資料結構“棧”實現

    是使用遞迴方法實現回溯演算法的,在第一次使用二維矩陣的情況下,又做了一次改一維的優化 但是演算法效率仍然差強人意,因為使用遞迴函式的緣故 下面提供另一種回溯演算法的實現,使用資料結構”棧“來模擬,遞迴函式的手工實現,因為我們知道計算機在處理遞迴時的本質就是棧 時間複雜度是一樣的,空間

    8皇后以及N皇后演算法探究,回溯演算法JAVA實現,遞迴方案(一)

    八皇后問題,是一個古老而著名的問題,是回溯演算法的典型案例。該問題是國際西洋棋棋手馬克斯·貝瑟爾於1848年提出:在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。 高斯認為有76種方案。1854年在柏林的象棋雜誌

    回溯法求解數問題的思路和程式碼

    在刷題的時候遇到了一個求解數獨的問題,用回溯法寫了以下程式碼,記錄一下,之後探究有沒有更好的演算法。 演算法思路: ①讀取待求解陣列,其中待填位置為0。 ②將所有待填位置的兩個座標(行列)和目前數字封裝起來壓入棧1中。 ③開一個

    演算法實踐——舞蹈鏈(Dancing Links)演算法解數

    本文介紹該演算法的實際運用,利用舞蹈鏈(Dancing Links)演算法求解數獨 在前文中可知,舞蹈鏈(Dancing Links)演算法在求解精確覆蓋問題時效率驚人。 那利用舞蹈鏈(Dancing Links)演算法求解數獨問題,實際上就是下面一個流程 1、把數獨問題轉換為精確覆蓋問題 2

    符號三角形問題—回溯演算法java實現

    問題描述:    下圖是由14個“+”和14個“-”組成的符號三角形。2個同號下面都是“+”,2個異號下面都是“-”:                        符號三角形第一行有n個符號,符號三角形問題要求對於給定的n,計算有多少個不同的符號三角形,使其所含的“+”和“

    LeetCode——電話號碼的字母組合(java)——回溯演算法

    給定一個僅包含數字 2-9 的字串,返回所有它能表示的字母組合。給出數字到字母的對映如下(與電話按鍵相同)。注意 1 不對應任何字母。示例:輸入:"23" 輸出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. 說明:儘管上面的答案是按字典序排列的

    走迷宮回溯演算法Java實現)

    以一個M×N的長方陣表示迷宮,0和1分別表示迷宮中的通路和障礙。設計一個程式,對任意設定的迷宮,求出一條從入口到出口的通路,或得出沒有通路的結論。 (1) 根據二維陣列,輸出迷宮的圖形。 (2) 探索迷宮的四個方向:RIGHT為向右,DOWN向下

    DLX演算法及應用(一)DLX模板+解數

    DLX演算法 原理:網上太多了,我就不寫了。。 用途:解決精確覆蓋問題 下面的程式碼是嚴格按照演算法寫的,其實對於這種沒有資料域的連結串列,是可以用陣列進行模擬的(見DLX演算法及應用(二)Matlab解數獨)。 程式碼中全部都用的是vector,更通用一些~ 後半部分給

    解數回溯法)

    //數獨大概長這樣規則就是在空格中填寫1~9的數字,每一行,每一列,還有每個區域(如上不同顏色的3*3區域)都只能由1~9的一組數字組成也就是說同行,同類,同區域不能有相同的數字input:5 * * * * 7 * * 6* 6 * * * * 5 * 4* 8 3 4 *

    Java實現: 解數

    題目 編寫一個程式,通過已填充的空格來解決數獨問題。 一個數獨的解法需遵循如下規則: 數字 1-9 在每一行只能出現一次。 數字 1-9 在每一列只能出現一次。 數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次。 空白格用 '.' 表示。 演算法

    個人項目-數終局生成與解數

    ima github 數獨 analysis tro AR war per https 1、先給出在這個小項目的開發過程中各個階段的程序及相關文檔 https://github.com/xulink/sudoku; 2、 PSP2.1