PostgreSQL 生成任意基数数独 - 4
标签
PostgreSQL , 数独 , 求解 , 动态规划
背景
使用《PostgreSQL 生成任意基数数独 - 3》 提供的方法,可以生成有解数独。在不知道数独答案的情况下,如何暴力破解呢?
实际上可以修改一下《PostgreSQL 生成任意基数数独 - 2》 里面的随机生成数独的函数,破解数独。
破解数独函数如下
create or replace function resolve_sudoku( vsudoku int[] -- 求解数独
) returns int[] as $$
declare res int[]; -- 结果 dims int := array_length(vsudoku,1); -- X,Y,BOX集合元素个数 dim int := sqrt(dims); -- 基数 vxyb xyb[]; -- 存储每个像素在XYB方向上未填充的元素个数 x int; -- 从xyb[]集合中,按指定方法选中一个像素。 X坐标 y int; -- 从xyb[]集合中,按指定方法选中一个像素。 Y坐标 vloops int := 2*dims; -- 计算N次(实际上就是随机多少次能覆盖到所有的值,值的取值空间为dims,通常来说执行DIMS次,能覆盖到所有的随机数) vloop int :=0; -- 计算N次计数器 cnt int := 0; -- 统计当前数独总共填充了多少个元素 rand int; -- 随机值
begin -- 求解 res := vsudoku; loop -- 生成每个像素X,Y,B方向的未知值个数 select comp_xyb(res, dim) into vxyb; -- 选择下一个要填充的像素(根据未知值个数排行,从总未知值最多,按单轴最多的位置中随机取一个位置) select ax,ay into x,y from unnest(vxyb) t where t.x+t.y+t.b <> 0 order by (t.x+t.y+t.b) desc , greatest(t.x,t.y,t.b) desc limit 1; -- 如果全部为0,0,0,说明已解完,返回res。 if not found then raise notice '计算有解,计算%次,结束。', cnt; return res; end if; -- 初始化以下计算循环次数 vloop := 0; loop -- 生成随机值 rand := 1+(random()*(dims-1))::int; -- 这轮循环无法生成并返回空 if vloop >= vloops then raise notice '本像素已循环%次,计算无解。已填充%个元素。无解数独如下: %', vloop, cnt, res; -- return res; return null; end if; -- 循环次数+1 vloop := vloop+1; -- 横向验证 perform 1 where array(select res[x][generate_series(1,dims)]) && array[rand]; if found then continue; end if; -- 纵向验证 perform 1 where array(select res[generate_series(1,dims)][y]) && array[rand]; if found then continue; end if; -- BOX验证 perform 1 where array( select res[xx][yy] from (select generate_series(((((x-1)/dim)::int)*dim)+1, ((((x-1)/dim)::int)*dim)+dim) xx) t1, (select generate_series(((((y-1)/dim)::int)*dim)+1, ((((y-1)/dim)::int)*dim)+dim) yy) t2 ) && array[rand]; if found then continue; end if; -- 这个像素值,通过验证 res[x][y] := rand; -- raise notice 'res[%][%] %', x, y, rand; -- 通过验证并跳出循环,找下一个需要填充的像素 cnt := cnt+1; exit; end loop; end loop;
end;
$$ language plpgsql strict volatile;
例子
1、首先按难易程度生成几个数独
postgres=# select gen_sudoku_question(20); gen_sudoku_question
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {{1,6,7,9,5,8,4,3,2},{9,5,8,4,3,2,1,6,7},{4,3,2,1,6,7,9,5,8},{6,7,1,5,8,9,3,2,4},{5,8,9,3,2,4,6,7,1},{3,2,4,6,7,1,5,8,9},{7,1,6,8,9,5,2,4,3},{8,9,5,2,4,3,7,1,6},{2,4,3,7,1,6,8,9,5}} {{1,0,7,9,0,8,4,3,2},{9,0,8,0,3,2,0,6,7},{4,3,2,1,6,7,0,5,8},{6,0,1,0,8,9,0,2,4},{5,0,9,3,2,4,0,7,1},{3,2,0,6,7,1,5,8,9},{7,1,0,0,0,5,0,4,3},{0,9,5,2,4,0,7,1,6},{0,4,3,7,0,6,8,9,5}}
(2 rows) postgres=# select gen_sudoku_question(41);
NOTICE: relation "tmp_sudoku" already exists, skipping gen_sudoku_question
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {{5,3,9,2,6,7,1,4,8},{1,4,8,5,3,9,2,6,7},{2,6,7,1,4,8,5,3,9},{9,5,3,7,2,6,8,1,4},{8,1,4,9,5,3,7,2,6},{7,2,6,8,1,4,9,5,3},{3,9,5,6,7,2,4,8,1},{4,8,1,3,9,5,6,7,2},{6,7,2,4,8,1,3,9,5}} {{5,0,0,2,0,7,1,0,8},{0,4,0,0,0,9,0,6,7},{2,0,7,0,0,0,0,0,0},{9,0,3,0,2,6,8,1,4},{0,1,0,0,0,0,7,0,6},{0,0,6,0,0,0,0,5,3},{0,9,0,6,0,2,4,0,1},{4,8,0,0,9,0,6,7,2},{6,0,2,4,0,1,0,0,5}}
(2 rows) postgres=# select gen_sudoku_question(51);
NOTICE: relation "tmp_sudoku" already exists, skipping gen_sudoku_question
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {{3,4,5,8,1,6,2,9,7},{8,1,6,2,9,7,3,4,5},{2,9,7,3,4,5,8,1,6},{4,5,3,1,6,8,9,7,2},{1,6,8,9,7,2,4,5,3},{9,7,2,4,5,3,1,6,8},{5,3,4,6,8,1,7,2,9},{6,8,1,7,2,9,5,3,4},{7,2,9,5,3,4,6,8,1}} {{0,4,5,0,0,6,2,9,0},{8,1,0,0,0,0,0,4,0},{2,0,0,3,4,0,8,0,6},{0,0,3,1,6,8,0,0,0},{0,0,8,0,0,0,4,5,0},{0,0,0,4,0,0,1,6,0},{0,0,0,0,0,1,0,0,9},{6,0,0,7,0,0,0,3,4},{0,0,0,0,0,0,0,0,1}}
(2 rows)
2、使用上面创建的函数破解数独
填充20个值的数独基本上秒解。
postgres=# select res from (select resolve_sudoku('{{1,0,7,9,0,8,4,3,2},{9,0,8,0,3,2,0,6,7},{4,3,2,1,6,7,0,5,8},{6,0,1,0,8,9,0,2,4},{5,0,9,3,2,4,0,7,1},{3,2,0,6,7,1,5,8,9},{7,1,0,0,0,5,0,4,3},{0,9,5,2,4,0,7,1,6},{0,4,3,7,0,6,8,9,5}}'::int[]) res from generate_series(1,100) ) t where t.res is not null ;
res
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {{1,6,7,9,5,8,4,3,2},{9,5,8,4,3,2,1,6,7},{4,3,2,1,6,7,9,5,8},{6,7,1,5,8,9,3,2,4},{5,8,9,3,2,4,6,7,1},{3,2,4,6,7,1,5,8,9},{7,1,6,8,9,5,2,4,3},{8,9,5,2,4,3,7,1,6},{2,4,3,7,1,6,8,9,5}}
(1 row)
但是对于需要填充41个,51个的,这种暴力尝试的方式,跑1000次也解不出来。
还是需要一个非常行之有效的。
目前的暴力破解存在的问题,一个值一旦确定下来(XYB方向满足约束)之后,后面就不会去修正它,从而导致了一个错误后面的计算全是浪费的。增加了破解成本。
扩展
在数据库中执行计划也与之类似,目前大多数执行计划是静态的,一旦执行计划确定下来了,后面就只能按照执行计划执行,无法中途调整。
所以,动态执行计划也成为目前很多数据库优化器突破的方向,在执行过程中,根据执行过程中的统计信息,不断修正执行计划,达到最佳的目的。
实际上,导航也与之类似,如果你根据当前的路况规划好了导航,在行驶过程中,可能某些路段发生了变化(拥堵情况),静态导航就无法修正这样的问题,还是按一开始既定的线路行驶。而动态导航,可以根据实时路况进行修正,选择下一跳。
在生产中有很多类似的例子,比如数据路由,负载均衡等等。
PostgreSQL 生成任意基数数独 - 4相关推荐
- php 输出任意一个数,php 生成任意范围的水仙花数
水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI).自恋数.自幂数.阿姆斯壮数或阿姆斯特朗数(Armst ...
- python生成订单号或生成任意序列
python生成订单号或生成任意序列 示例代码: import time# 生成订单号 def get_order_code():# 年月日时分秒+time.time()的后7位order_no = ...
- VBA实现两种方法生成任意概率分布的随机数
引子 一把武器的品质有分为最下级.下级.中级.上级.最上级五档,我希望在击杀一只怪物的时候,这把武器的掉率:最下级>下级>中级>上级>最上级,问如何设计满足上面的需求? 在游戏 ...
- python随机生成车牌_Python实现随机生成任意数量车牌号
之前做课设的时候舍友遇到了需要生成500w量级车牌号的问题,于是我便写了一个随机生成车牌号的程序,希望各位采纳. 注:Python实现 import random def chepaihao(len= ...
- crc生成多项式怎么算_利用system Verilog生成任意CRC多项式
IC君的第43篇原创文章 之前有一篇文章讲了CRC串行和并行电路的实现:CRC算法的硬件电路实现:串行电路和并行电路. 有做过类似设计的同学问:有没有办法轻松愉快地生成任意CRC多项式的电路?我们在设 ...
- 我的Python脚本——生成任意波形并存为txt
我的Python脚本--生成任意波形并存为txt 一. 脚本功能 根据采样点数,采样周期数等参数以及波形的数学表达式,生成任意波形 将波形数据转为指定位宽的二进制补码,然后存为txt 绘制原始波形和转 ...
- python批量生成图片_利用Python批量生成任意尺寸的图片
实现效果 通过源图片,在当前工作目录的/img目录下生成1000张,分别从1*1到1000*1000像素的图片. 效果如下: 目录结构 实现示例 # -*- coding: utf-8 -*- imp ...
- python批量生成图_利用Python批量生成任意尺寸的图片
实现效果 通过源图片,在当前工作目录的/img目录下生成1000张,分别从1*1到1000*1000像素的图片. 效果如下: 目录结构 实现示例 # -*- coding: utf-8 -*- imp ...
- python实现给定信号生成任意信噪比的带噪声信号
python实现给定信号生成任意信噪比的带噪声信号 产生叠加高斯白噪声的带噪语音 功能: 输入x为需加噪的信号,是一个numpy的1D张量 输入snr为设定信噪比,单位为dB,是一个32为的float ...
- 软工个人项目之生成和求解数独
软工个人项目之生成和求解数独 在这次完成个人项目的过程中,我第一次尝试了写csdn博客,用vs进行性能分析,在vs里面写单元测试,这次收获了很多.虽然还有很多需要改进的地方,但我会做得越来越好的~ 1 ...
最新文章
- oracle无创建directory权限,【DIRECTORY】普通用户创建Oracle DIRECTORY数据库对象的权限需求及探索...
- 不降低scipy版本解决AttributeError: module ‘scipy.misc‘ has no attribute ‘imresize‘问题
- IDEA 中比较骚后缀补全技巧!你可能没用过
- 网站外链如何发布才能更快的得到高排名呢?
- Java NIO之套接字通道
- python 爬取全量百度POI
- mysql去掉两个最高分_MySQL中查询、删除重复记录的方法大全
- 一文了解11个常见的多变量分析方法!
- KindEditor实现上传图片与回显
- 搭建服务器处理系统(基于netty),基于Netty的农业物联网服务器系统设计.PDF
- NoSQL:文档数据库
- 软件架构-事件驱动架构
- 「luogu4093」[HEOI2016/TJOI2016]序列
- 多个Excel文件独立窗口打开方式(一键解决)
- bin是什么文件,要如何打开?
- STC12C5A60S2独立PWM
- 人到底是为了什么活着?
- 机器学习分类器模型评价指标
- 【研究生】Yann LeCun、吴恩达等的2019年AI趋势预测
- Docker与k8s
热门文章
- 凯撒密码加密算法python_想偷WiFi?万能钥匙不行?试试用python一键破解!
- 软件测试面试题 背完面试没问题 亲测
- uniapp快速开发微信、支付宝app支付
- 网页版office服务器,Office 网页版服务说明
- MyEclipse中SVN分支合并到主干
- bodymovin_基于Bodymovin在Vue上渲染After Effects动画
- 专访数据挖掘领头人韩家炜教授:不要迷信权威,做学问要秉承「三个真实」...
- 莫烦python进化算法_使用遗传算法解决TSP问题(莫烦python 学习笔记)
- 吃鸡游戏计算机配置,运行端游吃鸡要什么配置
- python飞机大战源码素材包_Python飞机大战实战项目案例