数独问题流程图_数独求解算法
前言
周末两天,闲来无事,于是花了半天把自己很久就想研究的数独求解进行了算法实现。
初级玩法
首先看一下数独
屏幕快照 2018-03-25 下午6.30.52.png
数独规则
数独的规则比较简单:
每一行包括了1到9的数字,并且不能重复。
每一列包括了1到9的数字,并且不能重复。
每一组包括了1到9的数字,并且不能重复。
玩数独求解的流程
步骤一:从上到下,从左到右选择一个空单元。
步骤二: 根据这个单元所在的行、列、组,求出这个单元可能的解。
步骤三:随机抽取一个未论证的解作为单元的解进行填入,进行步骤一。
步骤四:如果步骤三中这个单元的所有未论证的解为空,则说明上一次随机填入有误。机型步骤五。
步骤五:退到上一个单元,将上一次随机填入解从未论证随机解中删除,进行步骤三。
步骤六:如果步骤二中这个单元的所有可能解为空,则说明上一次随机填入有误,进行步骤五。
步骤七:如果发现已经无法选择单元,即单元已经填满,说明完成解数独。
流程图:
shuduprocess.jpg
总体而言,整个过程是一个选择空单元,求合适解,选择未论证解,论证,论证之后再返回的过程。
代码实现
算法的实现步骤
输入
获取一个大小为81的范围为0-9的整型数组,0代表空。
新建一个9*9的二维单元结点数组,每个节点保存节点的位置,并将整形数组的值传给节点。
新建9个列的节点数组集合,9个行的节点数组集合,9个组的节点数组集合。每个节点保存保存所在列的节点数组集合,所在行的节点数组结合,所在组的节点数组结合。
输入代码
private void initData(char[] charArray) {
//新建各个节点对应步骤二
soduNodes = new SoduNode[9][9];
for (int i = 0; i < 9; i++) {
for (int k = 0; k < 9; k++) {
SoduNode soduNode = new SoduNode();
soduNode.value=charArray[i*9+k]-'0';
soduNode.xPosition=k;
soduNode.yPosition=i;
soduNodes[i][k]=soduNode;
}
}
//每个节点保存保存所在列的节点集合,所在行的节点集合,所在组的结合。对应步骤三
for(int i=0 ;i<9;i++){
SoduNode [] listNode=new SoduNode[9];
for(int k=0;k<9;k++){
listNode[k]=soduNodes[i][k];
soduNodes[i][k].listNode=listNode;
}
System.out.println("listNode:"+SoduNode.getNodesValue(listNode));
}
for(int i=0 ;i<9;i++){
SoduNode [] rowNode=new SoduNode[9];
for(int k=0;k<9;k++){
rowNode[k]=soduNodes[k][i];
soduNodes[k][i].rowNode=rowNode;
}
System.out.println("rowNode:"+SoduNode.getNodesValue(rowNode));
}
for(int i=0;i<=2;i++){
for(int k=0;k<=2;k++){
SoduNode [] groupNode=new SoduNode[9];
int index=0;
int middlex=3*i+1;
int middley=3*k+1;
for(int j=-1;j<=1;j++){
for(int l=-1;l<=1;l++){
groupNode[index]=soduNodes[middlex+j][middley+l];
soduNodes[middlex+j][middley+l].groupNode=groupNode;
index++;
}
}
System.out.println("groupNode:"+SoduNode.getNodesValue(groupNode));
}
}
}
求解
代码求解过程与玩数独的流程基本一致:
核心代码
//对应步骤一
private boolean getNextNodeAndCheck() {
SoduNode lastNullNode = getNextNullNode(); //步骤二
if(lastNullNode==null){
return true;
} //对应步骤七
Integer[] suitValue = lastNullNode.getSuitValue();
if(suitValue==null||suitValue.length==0){
System.out.println("no have suitable value");
return false;
}//对应步骤六
for(int i=0;i
lastNullNode.value=suitValue[I];//步骤三
//对应步骤一
if(getNextNodeAndCheck()){
return true;
}
}
return false;//所有可能解都已经论证完,无需论证解,对应步骤四
}
获取可能解的过程
Integer[] getSuitValue() {
TreeSet notSuits = new TreeSet<>();
TreeSet allValue= new TreeSet();
for (int i = 0; i <= 8; i++) {
if (listNode[i].value != 0) {
notSuits.add(listNode[i].value);
}
if (rowNode[i].value != 0) {
notSuits.add(rowNode[i].value);
}
if (groupNode[i].value != 0) {
notSuits.add(groupNode[i].value);
}
allValue.add(allChar[i]);
}
int notSuitSize = notSuits.size();
if (notSuitSize == 9) {
return null;
}
allValue.removeAll(notSuits);
System.out.println("allValue :" + getTreeValue(allValue));
Integer[]suitValue=new Integer[allValue.size()];
Iterator iterator = allValue.iterator();
int suitValueIndex=0;
while(iterator.hasNext()){
suitValue[suitValueIndex]=iterator.next();
suitValueIndex++;
}
System.out.println("suitValue size:"+suitValue.length+" value:"+getSuitsValue(suitValue));
return suitValue;
}
获取可能解的逻辑为
1.获取节点所在列、行、组所有存在的值的集合
2.将一个1到9的集合减掉存在值的集合即为可能解
运行
将上图数独求解
请输入81个数字代表数独:/n
009100000040078023600402001032680057895000030064310000407863915008590762956721040
initdata is :
0 0 9 1 0 0 0 0 0
0 4 0 0 7 8 0 2 3
6 0 0 4 0 2 0 0 1
0 3 2 6 8 0 0 5 7
8 9 5 0 0 0 0 3 0
0 6 4 3 1 0 0 0 0
4 0 7 8 6 3 9 1 5
0 0 8 5 9 0 7 6 2
9 5 6 7 2 1 0 4 0
resut is :
2 8 9 1 3 6 5 7 4
5 4 1 9 7 8 6 2 3
6 7 3 4 5 2 8 9 1
1 3 2 6 8 9 4 5 7
8 9 5 2 4 7 1 3 6
7 6 4 3 1 5 2 8 9
4 2 7 8 6 3 9 1 5
3 1 8 5 9 4 7 6 2
9 5 6 7 2 1 3 4 8
联系我
数独问题流程图_数独求解算法相关推荐
- 数独问题流程图_数独游戏的难度等级分析及求解算法研究
2 数独难度等级 数独游戏发展至今, 在数独爱好者的积极探索下, 求解数独的算法众多, 有 矩形顶点删减法.关键数删减法等 [7] .解答一道数独问题是一种或多种方法相互 结合, 为了使玩家能循环渐进 ...
- 数独问题流程图_软件工程基础大项目——数独问题
Github项目地址:https://github.com/WX78yyj/sudoku(由于自己有不爱命名的坏习惯,所以忘记命名了,结果提交的文件名称是未命名3,发现还改不了,郁闷) PSP2.1 ...
- 递归算法 流程图_什么是算法?如何学习算法?算法入门
转自:http://www.cnblogs.com/jiangwz/p/7765694.html 算法 什么是算法? 有一个很著名的公式 "程序=数据结构+算法". 曾经跟朋友吃饭 ...
- 递归算法 流程图_什么是算法?如何学习算法?算法入门的学习路径
什么是算法? 有一个很著名的公式 "程序=数据结构+算法". 曾经跟朋友吃饭的时候我问他什么是算法,他说算法嘛,就是一套方法,需要的时候拿过来,套用就可以,我吐槽他,他说的是小学数 ...
- raptor五个数排序流程图_数据结构与算法(一):排序(上)
做这个系列一是记录自己的学习过程,二是整合目前我所接触的比较好的资料,给出最直观,最通俗的算法解释 总体概况 十大排序算法:(比较排序):冒泡.选择.插入.归并.快速.希尔.堆排序 基数排序.桶排序. ...
- python数独游戏源代码_数独源程序py
#!/usr/bin/python #coding=utf-8 #sudoku # import random class sudoku(object): def __init__(self): se ...
- 选择排序算法流程图_常用排序算法之选择排序
前两天给大家分享了冒泡排序和插入排序(没关注的同学,可以关注后查看历史消息),今天继续给大家分享另一种常用的排序算法--选择排序. 选择排序 选择排序和插入排序很相似,也区分已排序区间和未排序区间,选 ...
- 数独求解算法_我如何回到一个老问题,终于写了一个数独求解算法
数独求解算法 by Ali Spittel 通过Ali Spittel 我如何回到一个老问题,终于写了一个数独求解算法 (How I came back to an old problem and f ...
- java数独流程图_九宫格数独游戏C语言解法
最近几天深圳一直下雨,一个人闷在屋里很是无聊,偶然打开一个小游戏网站看到了我的最爱--九宫格数独游戏.共有1-5五个难度级别,像我这种资深玩家其他难度就不用考虑了,冲着难度5的题目就去了,结果做地汗流 ...
- python数独伪代码回溯法_数独 #回溯算法 #CTF
1. intro:巅峰极客的一道逆向 刷巅峰极客2020里的rev题fu!kpy,复杂得不行但是看到if d[1][0] != '8' or d[1][7] != '2'和if check(h1) ! ...
最新文章
- 链mysql_mysql 版本链机制 readView
- mysql用if判断关联的表_mysql表连接,子查询以及if判断
- 机器学习实战(用Scikit-learn和TensorFlow进行机器学习)(八)
- SAP CRM settype的创建,背后发生了什么
- 关于node-sass和sass-loader安装上去的时候的时候报错的问题
- git add 命令的一个习惯用法:逐个挑选改动
- vc读取北通手柄按键_《噬血代码》手柄怎么操作 北通手柄按键功能详解
- I have to mention the search function at the
- abb机器人写字程序实例_abb机器人程序实例
- Windows2003 WINS 服务
- Mobileye/博世/大陆智驾份额「持续下滑」,本土供应商「起势」
- imac 蓝牙机械键盘_最好的蓝牙机械键盘
- 联想台式计算机 不启动u盘,联想电脑不能u盘启动怎么办
- 【数字图像处理 8】形态学图像处理
- 微信小程序怎么获取到data数据?
- mysql数据库熔断_服务熔断
- win7触摸板怎么关闭_笔记本fn键失灵怎么办?
- 高三学生早恋怎么处理?家长该怎么做?
- onedrive登陆以后是白板,我下载了onedrive以后,安装到登陆界面,输入账号,提示:我们的系统中没有 - Microsoft Community...
- 2011年11月校园招聘JAVA面试题整理
热门文章
- java 客户端调用 Tuxedo中间件
- live555传输实时h264视频流和mp3音频流
- [VB.NET]请教一个如何对姓名进行同音字查询?
- 【数学建模】相关软件
- adobe reader XI 打开后闪退(或过几秒后自动退出)【终极解决方案】
- 模拟集成电路设计基础知识(二):MOS管二级效应及其小信号等效
- 虚拟机xp系统联网问题
- iphone java模拟器_电脑java模拟器 模拟器游戏
- linux系统开机grub命令修复方法,linux系统GRUB修复
- [vue] 混入+替换对应文字实现简繁切换