当前位置:首页 » 操作系统 » 解数独算法

解数独算法

发布时间: 2022-06-22 14:42:05

① 有没有好的算法编程解决数独的正确答案

有啊,而且各种语言基本都有。
其中比较经典的舞蹈链算法对常见的标准数独来说简直就是秒解!甚至每秒解几千个几万个。

② 数独算法思路

数独(数和)(英:Cross Sums;日:カックロ)是一种数学智力游戏。数和把填字游戏和数独巧妙地结合在一起,采用填字游戏式的棋盘,解题时在空格中填上1-9的数字。这种游戏不仅需要逻辑思维能力,还需要一点加法运算。

电脑自动生成数独游戏的谜题

要得出所有满足条件的组合确实不是件容易的事情(主要是很多,打印起来很慢) 。但偶们的目标只是每次能得到一个新的组合,然后从格子里面随机遮掉一些数字就可以了。所以只需要在解数独游戏算法的基础上稍作修改即可。

所以,算法的步骤是:

1.往第一行或第一列随机填1-9的数字

2.调用解数独算法得到一个结果

3.每行随机遮掉1-8个数字。如果需要较大的难度,也可以将1-8改为2-8或3-8,等等。

以下是console工程的代码:

// sudoku.cpp : 定义控制台应用程序的入口点。
// by superarhow([email protected])

#include "stdafx.h"

#include "conio.h"

#define SUCCESS 1
#define _FAILED 0

/* 地图类型9*9的char,每个char从0-9,0表示待填 */
typedef char MAPTYPE[9][9];
/* 行数据,同时用作“可能性”数据。如LINETYPE a; 当a[0]为真时表示
当前位置可填1,a[1]为真时表示可填2,以此类推 */
typedef char LINETYPE[9];

typedef void (*ONMAPOKCALLBACK)(MAPTYPE map);

/* 打印地图 */
void mp_map(MAPTYPE dest)
{
for ( int j = 0; j < 9; j++ )
{
for ( int i = 0; i < 9; i++ )
{
printf("%d ", dest[i][j]);
}
printf("\n");
}
printf("\n");
}

int fill_line(MAPTYPE dest, int line, ONMAPOKCALLBACK callback);

/* 填下一个格子。本行的可能性已在调用前算好,要考虑的是列的可能性和九宫格的可能性 */
/* nums_possible : array (0-8) means possible of number (1-9) */
int fill_pos(MAPTYPE dest, LINETYPE nums_possible, int line, int pos, ONMAPOKCALLBACK callback)
{
if ( pos >= 9 )
{
return fill_line(dest, line + 1, callback);
}
if ( dest[pos][line] != 0 ) return fill_pos(dest, nums_possible, line, pos + 1, callback);
for ( int i = 0; i < 9; i++ )
{
if ( !nums_possible[i] ) continue;
/* 检查本列是否重复 */
int vetical_failed = 0;
for ( int j = 0; j < 9; j++ )
if ( dest[pos][j] == i + 1 )
{
vetical_failed = 1;
break;
}
if ( vetical_failed ) continue;
/* 检查九宫格是否重复 */
int nine_failed = 0;
int m = pos / 3;
int n = line / 3;
m *= 3;
n *= 3;
for ( int y = n; y < n + 3; y++ )
{
for ( int x = m; x < m + 3; x++ )
{
if ( dest[x][y] == i + 1 )
{
nine_failed = 1;
break;
}
}
if ( nine_failed ) break;
}
if ( nine_failed ) continue;
/* all ok, try next position */
dest[pos][line] = i + 1;
nums_possible[i] = 0;
if ( fill_pos(dest, nums_possible, line, pos + 1, callback) )
{
/* 本行已全部OK,尝试下一行 */
if ( fill_line(dest, line + 1, callback) ) return SUCCESS;
/* 下一行失败,重新尝试本位置的剩余可能性 */
}
nums_possible[i] = 1;
dest[pos][line] = 0;
}
return _FAILED;
}

/* 填下一行 */
int fill_line(MAPTYPE dest, int line, ONMAPOKCALLBACK callback)
{
if ( line >= 9 )
{
/* map */
callback(dest);
return SUCCESS;
}
LINETYPE nums;
LINETYPE saveline;
/* calc possibility(for the current line) */
for ( int i = 0; i < 9; i++ ) nums[i] = 1; /* all can be */
for ( int i = 0; i < 9; i++ )
{
char n = dest[i][line];
/* save line */
saveline[i] = dest[i][line];
if ( n != 0 ) nums[n - 1] = 0; /* appears */
}
if ( !fill_pos(dest, nums, line, 0, callback) )
{
/* restore line */
for ( int i = 0; i < 9; i++ ) dest[i][line] = saveline[i];
return _FAILED;
}
return SUCCESS;
}

MAPTYPE g_result;

void on_map_ok(MAPTYPE map)
{
memcpy(g_result, map, sizeof(MAPTYPE));
}

#include "windows.h"

int _tmain(int argc, _TCHAR* argv[])
{
MAPTYPE dest;
memset(dest, 0, sizeof(MAPTYPE));
srand( GetTickCount() );
/* 随机填充第一行 */
char ch[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for ( int i = 0; i < 9; i++ )
{
int p = rand() % 9;
char t = ch[p];
ch[p] = ch[i];
ch[i] = t;
}
for ( int i = 0; i < 9; i++ ) dest[i][0] = ch[i];
if ( fill_line(dest, 0, on_map_ok) )
{
/* 修剪掉一些块 */
for ( int i = 0; i < 9; i++ )
{
/* 调整n的取值范围可改变难度 %6 + 3是比较难的 */
int n = (rand() % 6) + 3;
for ( int j = 0; j < 9; j++ ) ch[j] = j; /* ch: index to erase */
for ( int j = 0; j < 9; j++ )
{
int p = rand() % 9;
char t = ch[p];
ch[p] = ch[i];
ch[i] = t;
}
for ( int j = 0; j < n; j++ ) g_result[ch[j]][i] = 0;
}
mp_map(g_result);
}
getch();
return 0;
}

看完这些,你对数独的算法了解了吗?

③ 请教九宫数独的算法

九宫一般用排除法做 比如1个任意格子的数字 他不能和所在行 列 宫已有数字相同 有些不确定的时候可以用假设法推 如果你假设的数字不正确到后面就会出现错误
http://ke..com/view/961.htm
网络上有比较详细的过程

④ 怎么用python解数独的算法题,给个矩阵里面填充了若干数,用程序自动给填充完整

classSolution:
#@paramboard,a9x92Darray
#-place.
#Donotreturnanyvalue.
defsolveSudoku(self,board):
self.board=board
self.solve()

deffindUnassigned(self):
forrowinrange(9):
forcolinrange(9):
ifself.board[row][col]==".":
returnrow,col
return-1,-1

defsolve(self):
row,col=self.findUnassigned()
#nounassignedpositionisfound,puzzlesolved
ifrow==-1andcol==-1:
returnTrue
fornumin["1","2","3","4","5","6","7","8","9"]:
ifself.isSafe(row,col,num):
self.board[row][col]=num
ifself.solve():
returnTrue
self.board[row][col]="."
returnFalse

defisSafe(self,row,col,ch):
boxrow=row-row%3
boxcol=col-col%3
ifself.checkrow(row,ch)andself.checkcol(col,ch)andself.checksquare(boxrow,boxcol,ch):
returnTrue
returnFalse

defcheckrow(self,row,ch):
forcolinrange(9):
ifself.board[row][col]==ch:
returnFalse
returnTrue

defcheckcol(self,col,ch):
forrowinrange(9):
ifself.board[row][col]==ch:
returnFalse
returnTrue

defchecksquare(self,row,col,ch):
forrinrange(row,row+3):
forcinrange(col,col+3):
ifself.board[r][c]==ch:
returnFalse
returnTrue

⑤ 数独的进阶解题方法

上述方法称为基础解法(Basic Techniques),其他所有的解法称为进阶解法(Advanced Techniques),是在补基本解法之不足,所以又称辅助解法。
进阶解法包括:区块摒除法(Locked Candidates)、数组法(Subset)、四角对角线(X-Wing)、唯一矩形(Unique Rectangle)、全双值坟墓(Bivalue Universal Grave)、单数链(X-Chain)、异数链(XY-Chain)及其他数链的高级技巧等等。已发展出来的方法有近百种之多。
其中前两种加上基础解法为一般数独书中介绍并使用的方法,同时也是大部分人可以理解并掌握的数独解题技法。
通过基础解法出数只需一种解法,摒除法或唯余法,超出此范围而需要施加进阶解法时,解题点需要进阶解法协助基础解法来满足隐性唯一或显性唯一才能出数,该解题点的解法需要多个步骤协力完成,因此称做组合解法。 相对概率不是真实的概率,而是用于同一格中的几个数字之间相互比较出现的可能。
相对概率 = 九宫格出现的概率 × 行出现的概率 × 列出现的概率
九宫格出现的概率:如果九宫格中有2个格可能出现1,目标格可能的数字为1、2、3,另一个格可能出现的数字为1、4,那么:目标格中的1在九宫格出现的概率 = 目标格中出现1的概率 × (1 - 另一个格中出现1的概率),得1/3 × (1-1/2) = 1/6。
注意:1-1/2表示另一个格不出现1的概率,1/3 × (1-1/2) 的意思就是在另一个格不出现1的情况下,目标格出现1的概率。
如果九宫格中有三个格可能出现1,目标格可能的数字为1、5、6,另一个格可能出现的数字为1、7,还有一个格可能出现的数字为1、8、9,得1/3 × (1-1/2) × (1-1/3) = 1/9。依此类推。
行出现的概率和列出现的概率与九宫格出现的概率的算法原理相同。最后,把三个概率相乘,得到相对概率,把目标格中3个数字的相对概率进行对比,相对概率越大,出现的可能性越大。 区块摒除法包括宫区块摒除法(Pointing)与行列区块摒除法(Claiming)。
在基础题里,利用区块摒除可以替代一些基础解法的观察,或辅助基础解法寻找焦点。
在非基础题里,区块可以隐藏任何其他结构,简单的可以把基础解法隐藏起来,难的可以隐藏数对等等其他进阶技巧。
例如:

首先数字6对第五宫摒除,得到第五宫的6在R4C5或者R6C5。
不论是在R4C5或者R6C5,C5的其他格都不能再有数字6。(R4C5与R6C5就是数字6的区块,这也是区块摒除作用的观点)
数字6对第二宫摒除,得解R1C4=6。

⑥ 数独算法

给你数独计算器:
http://blog.xunlei.com/web/category.html?uin=mianmiany1978&category_id=143
数独游戏:
http://blog.xunlei.com/web/category.html?uin=mianmiany1978&category_id=174
数独算法:
http://www.puzzle8.com/suku/news.asp
数独快速入门(上篇)
数独快速入门(中篇)
数独快速入门(下篇)
唯一解法
唯一候选数法
隐性三链数删减法
隐性数对删减法
三链列删减法
区块删减法
矩形顶点删减法
关键数删减法

补充:
合格的数独是只有唯一解。
而数独有难易度的分类,找一份报纸注意刊登的数独谜题是1星,还是5星。
在网络上,更分成容易题、进阶题、难题、极难题、超难题....
一般都是依据需要运用的技巧,而技巧是区分难易的。

数独不用猜测,解题全部是运用逻辑推理。
数独不用电脑程序分析,就可以解的题目是直观法数独题。
而超难题是需要电脑分析,及把全盘标示可选数,那是可选数谜题。
没有所谓解题通则。

1.直观解(一般报纸、书籍)
直观法技巧
直观法技巧 01 (容易级) 唯一解
直观法技巧 02 (容易级) 基本摒除
直观法技巧 03 (进阶级) 宫对行列摒除
直观法技巧 04 (进阶级) 行列对宫摒除
直观法技巧 05 (进阶级) 群组解法
直观法技巧 06 (困难级) X-Wing摒除法01
直观法技巧 06 (困难级) X-Wing摒除法02
直观法技巧 07 (困难级) 数偶摒除法

http://hi..com/kiwy07/blog/item/181fc482a153f3bd6c8119ab.html

2.可选数(以程序自动生成可选数)

Last value in block, row or column
Hidden Single in block
Hidden Single in row or column
Direct Pointing
Direct Claiming
Direct Hidden Pair
Naked Single
Direct Hidden Triplet
Pointing
Claiming
Naked Pair, X-Wing, Hidden Pair
Naked Triplet, Swordfish, Hidden Triplet
XY-Wing, XYZ-Wing
Unique rectangles and loops
Naked Quad, Jellyfish, Hidden Quad
Bivalue Universal Graves
Aligned Pair Exclusion
Bidirectioal X-Cycles and Y-Cycles
Forcing X-Chains
Forcing Chains, Bidirectional Cycles
Nishio
Cell/Region Forcing Chains
Dynamic Forcing Chains

http://diuf.unifr.ch/people/juillera/Sudoku/FAQ.html

通则无法解的题
直观难题
006589307
030602008
809703500
000891403
394265871
180374000
003026785
000458030
008037200
可选数极难题
970000000
003927000
008410709
300700400
060050070
007040003
105074900
000068507
786000042
不要把谜题解一次列出,而是找出下一步,及他的逻辑推理方法。
不要用猜测。

⑦ 请哪位大佬帮我设计一个破解数独游戏的算法。多谢啦!

1.联除法.
在并排的三个九宫格中的两排寻找相同数字,再利用九宫格得出另一排中该数字位置,该方法适用于中高级数独.
2.巡格法
找出在每个九宫格中出现频率较高的数字,得出该数字在其余九宫格内位置,该方法应用于方法一之后.
3.排它法
这个方法是解决问题的关键,易被常人所忽略.在各行列或九宫格中观察,若有个位置其它数字都不能填,就填余下的数字
4.待定法
此方法不常用却很有效.暂时确定某个数字在某个区域,再利用其来进行排除
5.行列法
此方法用于收官阶段,利用先从行列突破来提高解题效率.
6.假设法
作为一名高手,我不提倡这种方法.即在某个位置随机的填上一个数字,再进行推演,并有可能最终产生矛盾而否定结论.
7.频率法
这种方法相比于上一种方法更能提高效率.在某一行列或九宫格列举出所有情况,再选择某位置中出现频率高的数字
8.候选数法 使用候选数法解数独题目需先建立候选数列表,根据各种条件,逐步安全的清除每个宫格候选数的不可能取值的候选数,从而达到解题的目的。
使用候选数法一般能解比较复杂的数独题目,但是候选数法的使用没有直观法那么直接,需要先建立一个候选数列表的准备过程,所以实际使用时可以先利用直观法进行解题,到无法用直观法解题时再使用候选数法解题。
候选数法解题的过程就是逐渐排除不合适的候选数的过程,所以在进行候选数删除的时候一定要小心,确定安全地删除不合适的候选数,否则,很多时候只有重新做题了。有了计算机软件的帮助,使得候选数表的维护变得轻松起来。
数独直观法解题技巧主要有:唯一候选数法、隐性唯一候选数法、 区块删减法、数对删减法、隐性数对删减法、三链数删减法、隐性三链数删减法、矩形顶点删减法、三链列删减法、关键数删减法、关连数删减法。

⑧ 九宫格数独要怎么玩,详细高手教程有吗就是有没有什么算法啊啥的

数独顾名思义——每个数字只能出现一次。数独是一种源自18世纪末的瑞士,后在美国发展、并在日本得以发扬光大的数字谜题。数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次。这种游戏全面考验做题者观察能力和推理能力,虽然玩法简单,但数字排列方式却千变万化,所以不少教育者认为数独是训练头脑的绝佳方式。
数独解法全是由规则衍生出来的,基本解法分为两类思路,一类为排除法,一类为唯一法。更复杂的解法,最终也会归结到这两大类中。下边以图示简单介绍几种解法,只要你花几分钟看一遍,马上就可以开始做数独了。数独直观法解题技巧主要有:唯一解法、基础摒除法、区块摒除法、唯余解法、矩形摒除法、单元摒除法,余数测试法等。

⑨ 数独问题'高级数独没有更快捷的解答方式吗

计算机算法简介
本文所讨论的算法是一种通用算法,虽然不能说是最快的算法,但却可以求解所有的数独游戏。
算法准备:
1、一个可能性:表示某个格子可能填写的数字。
2、可能性数目:表示某个格子可能性的数量。为0表示已经确定。
3、区域标志:表示某个格子所在区域(小九宫)的ID,所有区域标志都是预定义的。
4、确定数量:表示所有数字已经确定的格子的数量,为81时则表示已经找到解。
5、整个九宫格用三个矩阵表示:可能性矩阵,数目矩阵,区域标志矩阵
算法的基本思想:
步骤1、将所有未确定的格子的可能性定义为0xFFFF(即所有数字都可能),可能数目为9。
步骤2、寻找所有确定的格子A(可能数目为0),在所有与A同行、同列和同区域的未确定的格子的可能性中减去与A相同的可能性。例如:A确定为9,则与A同行、同列和同区域(区域标志相同)的未确定的格子的可能性与0xFEFF按位与(除去可能性9),并将其可能性数目减少。
在除去可能性的过程中如果发现某个格子B的可能性数目由1减小为0,说明B和A只能取相同的数字,这可能是题目本身无解引起,也肯能是由于步骤3中搜索方向不对引起的,可认为此方向的搜索无解,退出这一方向的搜索。定义这个检查为唯一性检查。
步骤3、寻找所有未确定格子中可能性数目最少的格子M,如果M的可能性数目为1,则确定M:将M的可能性数目定义为0,并把确定数量加1,如果此时确定数量达到81,则报告找到解,否则,在所有与M同行、同列和同区域的未确定的格子的可能性中减去与M相同的可能性,并进行唯一性检查。然后重复步骤3。
如果M的可能性大于1,则把M假设为所有M的可能性,分多个方向进行搜索,在每一个搜索方向重复步骤3(这个可以用递归来实现)。
算法性能
本算法可以在50毫秒以内求解任意有解的数独游戏。

⑩ 数独解题的方法

原创回答:
建议你去OUBK网学习,那里有全面的数独技巧教学,每种技巧一片文章,文章不长,有一个小时就能看完,还有动态图的示例~
网站里还有大量的数独题目和解答过程~

数独解法一般分两类~一类是直观法,一类是候选法~
直观法(Direct Elimination Techniques)中,常用的算法包括:
单元唯一法 ( Sole Position Technique )
单元排除法 ( Basic Elimination Technique )
区块排除法 ( Block Elimination Technique )
唯一余数法 ( Sole Number Technique )
组合排除法 ( Combination Elimination Technique)
矩形排除法 ( Rectangle Elimination Technique)

在候选法中,常用的算法包括:
显式唯一法 (Naked Single)
隐式唯一法 (Hidden Single)
区块删减法 (Intersection Removal)
显式数对法 (Naked Pair)
显式三数集法 (Naked Triplet)
显式四数集法 (Naked Quad)
隐式数对法 (Hidden Pair)
隐式三数集法 (Hidden Triplet)
隐式四数集法 (Hidden Quad)
矩形对角线法 (X-wing)
XY形态匹配法(XY-wing)
XYZ形态匹配法(XYZ-wing)
三链数删减法 (Swordfish)
WXYZ形态匹配法(WXYZ-wing)

热点内容
c语言完美数 发布:2024-11-08 22:27:43 浏览:104
远程桌面服务器搭建h5网页吗 发布:2024-11-08 22:27:37 浏览:958
简单点编程 发布:2024-11-08 22:21:50 浏览:811
mysql存储过程教程 发布:2024-11-08 22:20:56 浏览:200
shell脚本sort 发布:2024-11-08 22:20:55 浏览:181
linux怎么登录 发布:2024-11-08 22:19:07 浏览:409
段页式存储管理中 发布:2024-11-08 22:03:22 浏览:733
易语言注册码源码 发布:2024-11-08 22:03:22 浏览:237
手游源码交易 发布:2024-11-08 21:58:03 浏览:150
快手极速版用户名和密码是多少 发布:2024-11-08 21:55:36 浏览:866