Java回溯演算法解數獨問題
下面來詳細講一下如何用回溯演算法來解數獨問題。
下圖是一個數獨題,也是號稱世界上最難的數獨。當然了,對於計算機程式來說,只要演算法是對的,難不難就不知道了,反正計算機又不累。回溯演算法基本上就是窮舉,解這種數獨類的問題邏輯比較簡單。
不管演算法懂不懂,先把類建出來,變數定義好,那放大學試卷上就是可以拿兩分了。
[java] view plain copy- package shudu;
- /**
- * Created by wolf on 2016/3/17.
- */
- public class Sudoku {
- private int[][] matrix;
- public Sudoku(int[][] matrix) {
- this.matrix = matrix;
- }
- public static
- // 號稱世界上最難數獨
- int[][] sudoku = {
- {8, 0, 0, 0, 0, 0, 0, 0, 0},
- {0, 0, 3, 6, 0, 0, 0, 0, 0},
- {0, 7, 0, 0, 9, 0, 2, 0, 0},
- {0, 5, 0, 0, 0, 7, 0, 0, 0},
- {0, 0, 0, 0, 4, 5, 7, 0, 0},
- {0, 0, 0, 1, 0, 0, 0, 3, 0},
- {0, 0, 1, 0, 0, 0, 0, 6, 8},
- {0, 0, 8, 5, 0, 0, 0, 1, 0},
- {0, 9, 0, 0, 0, 0, 4, 0, 0}};
- Sudoku s = new Sudoku(sudoku);
- s.backTrace(0, 0);
- }
- /**
- * 數獨演算法
- * @param i
- * 行號
- * @param j
- * 列號
- */
- private void backTrace(int i, int j) {
- }
- }
用一個二維陣列來儲存這個矩陣,然後定義一個方法來計算。方法裡有兩個屬性——行號和列號。
我們的原理就是從第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- package shudu;
- /**
- * Created by wolf on 2016/3/17.
- */
- public class Sudoku {
- private int[][] matrix;
- public Sudoku(int[][] matrix) {
- this.matrix = matrix;
- }
- public static void main(String[] args) {
- // 號稱世界上最難數獨
- int[][] sudoku = {
- {8, 0, 0, 0, 0, 0, 0, 0, 0},
- {0, 0, 3, 6, 0, 0, 0, 0, 0},
- {0, 7, 0, 0, 9, 0, 2, 0, 0},
- {0, 5, 0, 0, 0, 7, 0, 0, 0},
- {0, 0, 0, 0, 4, 5, 7, 0, 0},
- {0, 0, 0, 1, 0, 0, 0, 3, 0},
- {0, 0, 1, 0, 0, 0, 0, 6, 8},
- {0, 0, 8, 5, 0, 0, 0, 1, 0},
- {0, 9, 0, 0, 0, 0, 4, 0, 0}};
- Sudoku s = new Sudoku(sudoku);
- s.backTrace(0, 0);
- }
- /**
- * 數獨演算法
- *
- * @param i 行號
- * @param j 列號
- */
- private void backTrace(int i, int j) {
- //如果i行j列是空格,那麼才進入給空格填值的邏輯
-
相關推薦
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