思路

1.生成数独

数独的生成总体思路是挖洞法。

首先在二维数组第一行随机填充1-9 9个数字,然后将这9个数字随机分布到整个二维数组中,然后使用求解数独的算法对此时的数组进行求解,得到一个完整的数独,然后按照用户输入的提示数量进行随机挖洞,得到最终的数独题目。

这种方法理论上可以随机生成(81!/72! = 9.5e+16)种不同的数独题目,足够人类玩上几百年了。

2.求解数独

求解数独使用的是计算机最擅长的暴力搜索中的回溯法。并结合人求解数独的思维过程增加了一点改进。

在每一层搜索中,首先计算每个格子可以填充的值的个数(我命名为不确定度),如果有格子不确定度为1,则直接填上数字就好,否则对不确定度最小的格子使用可能的数字逐个填充,并进入下一次递归。如果发现不确定度为0的格子,做说明之前的过程有问题,需要进行回溯。

代码

package sudo;

import java.util.Scanner;

/**

* @description 数独生成和求解

* @limit 支持从1-80的数字提示数量

* @method 深度优先搜索/回溯法

* @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

/**

* 构造函数

* 初始化变量

*/

public Sudo(){

lef = 0;

for(int i=0;i<9;++i){

for(int j=0;j<9;++j){

data[i][j] = 0;

}

}

}

/**

* 生成数独

* 方法:挖洞法

*/

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个数字放在二维数组中随机位置*/

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;

}

/*通过9个数字求出一个可行解*/

solveSudo();

lef = 81 - tip;

for(int i=0;i

int ta = (int)(Math.random()*10)%9;

int tb = (int)(Math.random()*10)%9;

if(data[ta][tb]!=0)

data[ta][tb] = 0;

else

i--;

}

}

/**

* 求解数独

* @return 是否有解的boolean标识

*/

public boolean solveSudo(){

if(dfs()){

System.out.println("Solve completed.");

return true;

}else{

System.out.println("Error:There are no solution.");

return false;

}

}

/**

* 输出数独数组

*/

public void printSudo(){

System.out.println("-----------------");

for(int i=0;i<9;++i){

for(int j=0;j<9;++j){

if(data[i][j]>0)

System.out.print(data[i][j]+" ");

else

System.out.print("* ");

}

System.out.print('\n');

}

System.out.println("-----------------");

}

/**

* 计算某格子的可填数字个数,即不确定度

* @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调用的深度优先搜索

* @return 是否有解的boolean标识

*/

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

mincount = count;

mini = i;

minj = j;

}

}

}

/*优先处理不确定度最小的格子*/

calcount(mini,minj,mark);

for(int i=1;i<=9;++i){

if(mark[i]==0){

data[mini][minj] = i;

lef--;

dfs();

if(lef==0) return true;

data[mini][minj] = 0;//回溯法

lef++;

}

}

return true;

}

/**

* main函数

* @param args

*/

public static void main(String[] args) {

Sudo su = new Sudo();

su.genSudo();

su.printSudo();

su.solveSudo();

su.printSudo();

}

}

演示

以下四幅图分别是输出为0,20,60的程序运行结果。

java 数独算法_[Java] 数独生成和求解相关推荐

  1. java不规则算法_分布式id生成算法 snowflake 详解

    背景 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识.如在支付流水号.订单号等,随者业务数据日渐增长,对数据分库分表后需要有一个唯一ID来标识一条数据或消息,数据库的自增ID显然不能满足需 ...

  2. JAVA代码—算法基础:数独问题(Sodoku Puzzles)

    JAVA代码-算法基础:数独问题(Sodoku Puzzles) 数独问题(Sodoku Puzzles) 数独游戏(日语:数独 すうどく)是一种源自18世纪末的瑞士的游戏,后在美国发展.并在日本得以 ...

  3. java课程 数独 文库_通俗易懂的数独算法(java版)

    数独算法 一 知识背景 无 二 绪言 偶尔玩下休闲益智小游戏,一方面可以舒解下心情,另一方面刺激下大脑皮层.百度了一下数独的起源和概念.说了那么多,看着就累.精简一下就是数字(0-9)填充游戏.不明白 ...

  4. java python算法_用Python,Java和C ++示例解释的排序算法

    java python算法 什么是排序算法? (What is a Sorting Algorithm?) Sorting algorithms are a set of instructions t ...

  5. java python算法_用Java,Python和C ++示例解释的搜索算法

    java python算法 什么是搜索算法? (What is a Search Algorithm?) This kind of algorithm looks at the problem of ...

  6. java random算法_负载均衡--随机算法(Random)

    随机算法是指:从服务器列表中,随机选取一台服务器进行访问.由概率论可以得知,随着客户端调用服务端的次数增多,其实际效果趋近于平均分配请求到服务端的每一台服务器,也就是达到轮询的效果. 一.算法描述 假 ...

  7. java数据挖掘算法_[转载]干货,基于Java和C++的数据挖掘Apriori算法实现

    Apriori算法实现 Apriori算法的思想还是很容易理解的,实现起来虽然麻烦,但是还是比较容易的.下面是我使用Java语言实现的Apriori算法,实现了AprioriAlgorithm 类,包 ...

  8. java 线性回归算法_线性搜索或顺序搜索算法在Java中如何工作? 示例教程

    java 线性回归算法 大家好,之前,我讨论了二进制搜索算法的工作原理,并分享了在Java中实现二进制搜索的代码. 在那篇文章中,有人问我是否还有其他搜索算法? 如果数组中的元素未排序,又该如何使用它 ...

  9. java轮训算法_负载均衡轮询算法实现疑问

    import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; /* ...

  10. java fields是_一个快速生成R2.java中fields的插件

    一个快速生成R2.java中fields的插件 项目地址:github.com/JeasonWong/- 介绍 在子 module 中使用 ButterKnife 时,如果想使用 ButterKnif ...

最新文章

  1. 【更新】比较智能的爬取姓名
  2. Xcode8 及iOS10适配问题汇总
  3. LinkedList 实现 Queue
  4. 常用的正则表达式分享
  5. java统计 pv uv_统计PV、UV的新武器——Aviator
  6. java批量生成订单号_【笔记6-支付及订单模块】从0开始 独立完成企业级Java电商网站开发(服务端)...
  7. Web应用程序安全性:战斗自己或寻找理智的边缘
  8. istio_关于Istio的五件事
  9. ABAP Util代码
  10. 保存MATLAB工作区的矩阵为TXT文件
  11. vue学习笔记-10-常用特性之表单操作
  12. 分数阶微积分学薛定宇电子版_分数阶微积分学与分数阶控制 pdf epub mobi txt 下载...
  13. 计算机 在哪看是什么32位,如何查看自己的电脑是32位的还是64位
  14. 1、学生如何购买云服务器、域名(系列:个人博客搭建)
  15. 高层要有事业心,中层要有进取心,基层要有责任心!
  16. 时间格式化问题@DateTimeFormat和@JsonFormat的区别
  17. Linux中的文件IO以及JDK中的NIO模型简介
  18. ctf训练 web安全暴力破解
  19. 降糖奶粉真的降糖吗?育润胰力佳与阿尔发哪个控糖效果更好?
  20. MATLAB App Designer入门实战(三)

热门文章

  1. 运放全波整流电路_万能整流电路:运放+整流二极管
  2. 平行云CEO 李岩:CloudXR ,开启通往元宇宙的通道
  3. Android:JNI 与 NDK到底是什么?(含实例教学)
  4. 听完计算机知识讲座后感悟,计算机技能培训心得感想
  5. 如何对全站进行死链接检测?
  6. 腾讯地图如何根据经纬度获取地址
  7. [密码学]利用docker安装与使用sagemath
  8. HHL,AL;非结合朱顶红凝集素(HHL,AL)
  9. 解决找不到 C 盘中的 AppData 文件夹的问题
  10. 设计模式 - 桥接模式 ( Bridge ) 平时用的少