數獨java演算法
⑴ 數獨的計算公式是什麼
1、聯除法。
在並排的三個九宮格中的兩排尋找相同數字,再利用九宮格得出另一排中該數字位置,該方法適用於中高級數獨.
2、巡格法
找出在每個九宮格中出現頻率較高的數字,得出該數字在其餘九宮格內位置,該方法應用於方法一之後。
3、排除法
這個方法是解決問題的關鍵,易被常人所忽略。在各行列或九宮格中觀察,若有個位置其它數字都不能填,就填餘下的數字
4、待定法
此方法不常用卻很有效。暫時確定某個數字在某個區域,再利用其來進行排除
5、行列法
此方法用於收官階段,利用先從行列突破來提高解題效率。
6、假設法
即在某個位置隨機的填上一個數字,再進行推演,並有可能最終產生矛盾而否定結論。
7、頻率法
這種方法相比於上一種方法更能提高效率。在某一行列或九宮格列舉出所有情況,再選擇某位置中出現頻率高的數字
8、候選數法
使用候選數法解數獨題目需先建立候選數列表,根據各種條件,逐步安全的清除每個宮格候選數的不可能取值的候選數,從而達到解題的目的。
數獨的出題方法:
1、挖洞法
從有到無的出題方法。先生成一個終盤,然後挖去部分數字形成一道題目。
2、填數法
從無到有的出題方法。在一個空盤面上填上部分數字形成一道題目。2007年日本NPGenerator軟體的網站提出了一種邊推理邊出題的出題法,可以手工打造出漂亮圖案的數獨題目。
⑵ 數獨高級解法有哪些
具體如下:
1、聯除法:在兩行三個隔膜中查找相同的數字,然後用它們查找另一行中的位數。該方法適用於中、高級數獨。
2、巡格法:找出每個橫膈膜數字的頻率,找出它的位置。
3、排它法:這種方法是解決問題的關鍵,容易被普通老百姓所忽視。觀察隊列或橫膈膜,如果有一個位置不能被其他數字填補,填補剩下的數字。
4、待定法:這種方法不常使用,但很有效。在區域中臨時定位一個數字,並將其用於排除。
5、行列法:該方法用於提高破階求解問題的效率。
6、假設法:作為專家,我並不主張這種做法。
7 、頻率法:這種方法比以前的方法更有效。列出行中或框中的所有情況,然後選擇一個高頻率的數字。
8、用候選方法解決數獨問題的候選演算法首先,必須建立一個候選列表。在不同的條件下,每個宮格不可能的候選人可以逐步和安全地被清除。
候選數方法可以用來解決復雜的數獨問題,但是候選數方法的使用不像直覺方法那樣直接,需要建立候選人名單的准備過程,所以實際使用可以先用可視化方法解決問題,而不能用候選人的方法來解決問題。
候選人數方法的解決方法是逐步排除不合適候選數的過程,所以在刪除候選數時一定要小心,要確定刪除的候選人是否安全,否則,多次都要重做的問題。在電腦軟體的幫助下,使得候選數表的維護變得輕鬆起來。
常規解題手法:
依解題填制的過程可區分為直觀法與候選數法。
直觀法就是不做任何記號,直接從數獨的盤勢觀察線索,推論答案的方法。
候選數法就是刪減等位群格位已出現的數字,將剩餘可填數字填入空格做為解題線索的參考,可填數字稱為候選數(Candidates,或稱備選數)。
直觀法和候選數法只是填制時候是否有注記的區別,依照個人習慣而定,並非鑒定題目難度或技巧難度的標准,無論是難題或是簡單題都可上述方法填制,一般程序解題以候選數法較多。
⑶ 數獨的一般解法
516274398
793568412
824391765
451637289
372189654
968452137
235846971
649715823
187923546
-----------
舉例說明你的問題:
如圖,紅色宮內的9應該填在哪裡?
就要用到你所說的第4步。利用相對稱的兩個數組合3和5,來確定B5、B6兩個空格只能為35或53.從而排除B5、B6為9的可能。
紅色宮內的9填在哪裡,應該清楚了吧。
⑷ 數獨的計算公式是什麼
數獨的計算公式是每一橫行、每一豎行和每一斜行的和都等於15。
⑸ 求用java寫一個數獨游戲
public class ShuDu {
/**存儲數字的數組*/
static int[][] n = new int[9][9];
/**生成隨機數字的源數組,隨機數字從該數組中產生*/
static int[] num = {1,2,3,4,5,6,7,8,9};
public static void main(String[] args) {
//生成數字
for(int i = 0;i < 9;i++){
//嘗試填充的數字次數
int time = 0;
//填充數字
for(int j = 0;j < 9;j++){
//產生數字
n[i][j] = generateNum(time);
//如果返回值為0,則代表卡住,退回處理
//退回處理的原則是:如果不是第一列,則先倒退到前一列,否則倒退到前一行的最後一列
if(n[i][j] == 0){
//不是第一列,則倒退一列
if(j > 0){
j-=2;
continue;
}else{//是第一列,則倒退到上一行的最後一列
i--;
j = 8;
continue;
}
}
//填充成功
if(isCorret(i,j)){
//初始化time,為下一次填充做准備
time = 0;
}else{ //繼續填充
//次數增加1
time++;
//繼續填充當前格
j--;
}
}
}
//輸出結果
for(int i = 0;i < 9;i++){
for(int j = 0;j < 9;j++){
System.out.print(n[i][j] + " ");
}
System.out.println();
}
}
/**
* 是否滿足行、列和3X3區域不重復的要求
* @param row 行號
* @param col 列號
* @return true代表符合要求
*/
public static boolean isCorret(int row,int col){
return (checkRow(row) & checkLine(col) & checkNine(row,col));
}
/**
* 檢查行是否符合要求
* @param row 檢查的行號
* @return true代表符合要求
*/
public static boolean checkRow(int row){
for(int j = 0;j < 8;j++){
if(n[row][j] == 0){
continue;
}
for(int k =j + 1;k< 9;k++){
if(n[row][j] == n[row][k]){
return false;
}
}
}
return true;
}
/**
* 檢查列是否符合要求
* @param col 檢查的列號
* @return true代表符合要求
*/
public static boolean checkLine(int col){
for(int j = 0;j < 8;j++){
if(n[j][col] == 0){
continue;
}
for(int k =j + 1;k< 9;k++){
if(n[j][col] == n[k][col]){
return false;
}
}
}
return true;
}
/**
* 檢查3X3區域是否符合要求
* @param row 檢查的行號
* @param col 檢查的列號
* @return true代表符合要求
*/
public static boolean checkNine(int row,int col){
//獲得左上角的坐標
int j = row / 3 * 3;
int k = col /3 * 3;
//循環比較
for(int i = 0;i < 8;i++){
if(n[j + i/3][k + i % 3] == 0){
continue;
}
for(int m = i+ 1;m < 9;m++){
if(n[j + i/3][k + i % 3] == n[j + m/3][k + m % 3]){
return false;
}
}
}
return true;
}
/**
* 產生1-9之間的隨機數字
* 規則:生成的隨機數字放置在數組8-time下標的位置,隨著time的增加,已經嘗試過的數字將不會在取到
* 說明:即第一次次是從所有數字中隨機,第二次時從前八個數字中隨機,依次類推,
* 這樣既保證隨機,也不會再重復取已經不符合要求的數字,提高程序的效率
* 這個規則是本演算法的核心
* @param time 填充的次數,0代表第一次填充
* @return
*/
public static int generateNum(int time){
//第一次嘗試時,初始化隨機數字源數組
if(time == 0){
for(int i = 0;i < 9;i++){
num[i] = i + 1;
}
}
//第10次填充,表明該位置已經卡住,則返回0,由主程序處理退回
if(time == 9){
return 0;
}
//不是第一次填充
//生成隨機數字,該數字是數組的下標,取數組num中該下標對應的數字為隨機數字
int ranNum = (int)(Math.random() * (9 - time));
//把數字放置在數組倒數第time個位置,
int temp = num[8 - time];
num[8 - time] = num[ranNum];
num[ranNum] = temp;
//返回數字
return num[8 - time];
}
}