摘要:首先在二維數(shù)組第一行隨機(jī)填充個(gè)數(shù)字,然后將這個(gè)數(shù)字隨機(jī)分布到整個(gè)二維數(shù)組中,然后使用求解數(shù)獨(dú)的算法對(duì)此時(shí)的數(shù)組進(jìn)行求解,得到一個(gè)完整的數(shù)獨(dú),然后按照用戶輸入的提示數(shù)量進(jìn)行隨機(jī)挖洞,得到最終的數(shù)獨(dú)題目。
思路 1.生成數(shù)獨(dú)
數(shù)獨(dú)的生成總體思路是挖洞法。
首先在二維數(shù)組第一行隨機(jī)填充1-9 9個(gè)數(shù)字,然后將這9個(gè)數(shù)字隨機(jī)分布到整個(gè)二維數(shù)組中,然后使用求解數(shù)獨(dú)的算法對(duì)此時(shí)的數(shù)組進(jìn)行求解,得到一個(gè)完整的數(shù)獨(dú),然后按照用戶輸入的提示數(shù)量進(jìn)行隨機(jī)挖洞,得到最終的數(shù)獨(dú)題目。
這種方法理論上可以隨機(jī)生成(81!/72! = 9.5e+16)種不同的數(shù)獨(dú)題目,足夠人類玩上幾百年了。
求解數(shù)獨(dú)使用的是計(jì)算機(jī)最擅長(zhǎng)的暴力搜索中的回溯法。并結(jié)合人求解數(shù)獨(dú)的思維過(guò)程增加了一點(diǎn)改進(jìn)。
在每一層搜索中,首先計(jì)算每個(gè)格子可以填充的值的個(gè)數(shù)(我命名為不確定度),如果有格子不確定度為1,則直接填上數(shù)字就好,否則對(duì)不確定度最小的格子使用可能的數(shù)字逐個(gè)填充,并進(jìn)入下一次遞歸。如果發(fā)現(xiàn)不確定度為0的格子,做說(shuō)明之前的過(guò)程有問(wèn)題,需要進(jìn)行回溯。
package sudo; import java.util.Scanner; /** * @description 數(shù)獨(dú)生成和求解 * @limit 支持從1-80的數(shù)字提示數(shù)量 * @method 深度優(yōu)先搜索/回溯法 * @author chnmagnus */ public class Sudo { private int[][] data = new int[9][9]; //muti_array private int lef; //the number of zero in array private int tip; //the number of nozero_digit in array /** * 構(gòu)造函數(shù) * 初始化變量 */ public Sudo(){ lef = 0; for(int i=0;i<9;++i){ for(int j=0;j<9;++j){ data[i][j] = 0; } } } /** * 生成數(shù)獨(dú) * 方法:挖洞法 */ public void genSudo(){ System.out.println("Please input the number of digits provided:"); Scanner scan = new Scanner(System.in); tip = scan.nextInt(); scan.close(); /*將1-9 9個(gè)數(shù)字放在二維數(shù)組中隨機(jī)位置*/ lef = 81 - 9; for(int i=0;i<9;++i){ data[0][i] = i+1; } for(int i=0;i<9;++i){ int ta = (int)(Math.random()*10)%9; int tb = (int)(Math.random()*10)%9; int tem = data[0][ta]; data[0][ta] = data[0][tb]; data[0][tb] = tem; } for(int i=0;i<9;++i){ int ta = (int)(Math.random()*10)%9; int tb = (int)(Math.random()*10)%9; int tem = data[0][i]; data[0][i] = data[ta][tb]; data[ta][tb] = tem; } /*通過(guò)9個(gè)數(shù)字求出一個(gè)可行解*/ solveSudo(); lef = 81 - tip; for(int i=0;i0) System.out.print(data[i][j]+" "); else System.out.print("* "); } System.out.print(" "); } System.out.println("-----------------"); } /** * 計(jì)算某格子的可填數(shù)字個(gè)數(shù),即不確定度 * @param r * @param c * @param mark * @return 不確定度 */ private int calcount(int r,int c,int[] mark){ for(int ti=0;ti<10;++ti) mark[ti] = 0; for(int i=0;i<9;++i){ mark[data[i][c]] = 1; mark[data[r][i]] = 1; } int rs = (r/3)*3; int cs = (c/3)*3; for(int i=0;i<3;++i){ for(int j=0;j<3;++j){ mark[data[rs+i][cs+j]] = 1; } } int count = 0; for(int i=1;i<=9;++i){ if(mark[i]==0) count++; } return count; } /** * 供solve調(diào)用的深度優(yōu)先搜索 * @return 是否有解的boolean標(biāo)識(shí) */ private boolean dfs(){ if(lef==0) return true; int mincount = 10; int mini = 0,minj = 0; int[] mark = new int[10]; /*找到不確定度最小的格子*/ for(int i=0;i<9;++i){ for(int j=0;j<9;++j){ if(data[i][j]!=0) continue; int count = calcount(i,j,mark); if(count==0) return false; if(count 演示 以下四幅圖分別是輸出為0,20,60的程序運(yùn)行結(jié)果。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/65647.html
摘要:可以針對(duì)筆者常用的數(shù)獨(dú)本文的實(shí)現(xiàn)都基于該,實(shí)現(xiàn)數(shù)獨(dú)的識(shí)別求解并把答案自動(dòng)填入。專家級(jí)別的平均秒完成求解包括圖像數(shù)字提取,識(shí)別過(guò)程,完成全部操作。步驟四數(shù)獨(dú)求解,生成答案,并生成需要填充的數(shù)字序列。 1 序 ??數(shù)獨(dú)是源自18世紀(jì)瑞士的一種數(shù)學(xué)游戲。是一種運(yùn)用紙、筆進(jìn)行演算的邏輯游戲。玩家需要根據(jù)9×9盤面上的已知數(shù)字,推理出所有剩余空格的數(shù)字,并滿足每一行、每一列、每一個(gè)粗線宮(3*3...
摘要:數(shù)獨(dú)技巧直觀法候選數(shù)法相關(guān)二十格一個(gè)數(shù)字只與其所在行列及小九宮格的二十格相關(guān)我的思路精心設(shè)計(jì)了有效性判定函數(shù),最多一次遍歷個(gè)小單元格就能做出方案的有效性判定。 看《算法的樂(lè)趣》,試著用非遞歸窮舉來(lái)解數(shù)獨(dú),看效率如何! 數(shù)獨(dú)規(guī)則 數(shù)獨(dú)游戲,經(jīng)典的為9×9=81個(gè)單元格組成的九宮格,同時(shí)也形成了3×3=9個(gè)小九宮格,要求在81個(gè)小單元格中填入數(shù)字1~9,并且數(shù)字在每行每列及每個(gè)小九宮格中都...
摘要:而此處針對(duì)進(jìn)一步的搜索,有兩個(gè)問(wèn)題需要考慮如何選取搜索起點(diǎn)方格確定哪種搜索策略深度優(yōu)先搜索,廣度優(yōu)先搜索關(guān)于第一個(gè)問(wèn)題,無(wú)論選擇哪個(gè)方格起始搜索,對(duì)于能否解決問(wèn)題來(lái)說(shuō)并不存在差異。 Github倉(cāng)庫(kù)地址 學(xué)習(xí)是為了尋找解決問(wèn)題的答案,若脫離了問(wèn)題只為知曉而進(jìn)行的打call,那么隨時(shí)間流逝所沉淀下來(lái)的,估計(jì)就只有重在參與的虛幻存在感了,自學(xué)的人就更應(yīng)善于發(fā)現(xiàn)可供解決的問(wèn)題。為了入門AI,...
摘要:前言最近的后臺(tái)管理系統(tǒng)頁(yè)面,功能暫時(shí)沒(méi)有新的需求,就在想首頁(yè)放什么東西,最近我想到的就是放個(gè)所謂的數(shù)獨(dú),為什么是所謂的數(shù)獨(dú),因?yàn)橐?guī)則不同于標(biāo)準(zhǔn)的數(shù)獨(dú),只要求每一行每一列數(shù)字不一樣就可以了這個(gè)實(shí)例也是基于的,代碼分享給大家。 1.前言 最近的后臺(tái)管理系統(tǒng)頁(yè)面,功能暫時(shí)沒(méi)有新的需求,就在想首頁(yè)放什么東西,最近我想到的就是放個(gè)所謂的數(shù)獨(dú),為什么是所謂的數(shù)獨(dú),因?yàn)橐?guī)則不同于標(biāo)準(zhǔn)的數(shù)獨(dú),只要求每...
閱讀 844·2019-08-30 15:54
閱讀 3315·2019-08-29 15:33
閱讀 2700·2019-08-29 13:48
閱讀 1212·2019-08-26 18:26
閱讀 3332·2019-08-26 13:55
閱讀 1475·2019-08-26 10:45
閱讀 1163·2019-08-26 10:19
閱讀 304·2019-08-26 10:16