利用DuckDB SQL求解集合数学题

已知集合I={1,2,3,4,5,6},A={(s,t)|s ∈I,t∈I},若B包含于A,且对任意的(a,b)∈B,(x,y)∈B,均有(a-x)(b-y)<=0,则集合B中元素个数的最大值是几?

sql 复制代码
set variable n=6;
with recursive i as(select i from range(1,getvariable('n')+1)t(i)),
a as(select 1::bigint<<((i1.i-1)*getvariable('n')+i2.i)m, i1.i s, i2.i t from i i1,i i2),
b as(select 1 lv,m,[(a,b),(x,y)]st from(select a.m+a1.m m,a.s a,a.t b,a1.s x,a1.t y from a,a a1 where a.m<a1.m) where (a-x)*(b-y)<=0 
union all
select lv+1,a.m+b.m,st +[(a.s,a.t)] from b,a where a.m>b.m /*and a.m & b.m=0*/ and not exists(select 1 from range(1,lv+2) un(nb) where (a.s-b.st[nb][1])*(a.t-b.st[nb][2])>0))
from b where lv=(select max(lv) from b);

求出的最大元素个数是11,一共有252个不同的集合满足要求。本来是需要用对二进制位与运算为0来判断的,但是由于低位全1也比高位1低位0的二进制数小,所以有了a.m>b.m,注释掉与运算判断也不影响结果。

也可以不用range笛卡尔积,而用unnest函数来实现,不过慢一点

sql 复制代码
set variable n=6;
with recursive i as(select i from range(1,getvariable('n')+1)t(i)),
a as(select 1::bigint<<((i1.i-1)*getvariable('n')+i2.i)m, i1.i s, i2.i t from i i1,i i2),
b as(select 1 lv,m,[(a,b),(x,y)]st from(select a.m+a1.m m,a.s a,a.t b,a1.s x,a1.t y from a,a a1 where a.m<a1.m) where (a-x)*(b-y)<=0 
union all
select lv+1,a.m+b.m,st +[(a.s,a.t)] from b,a where a.m>b.m and not exists(select 1 from unnest(b.st) un(nb) where (a.s-nb[1])*(a.t-nb[2])>0))
from b where lv=(select max(lv) from b);

比起python程序,SQL还是简练一点。

相关推荐
辰烨chenye30 分钟前
LeetCode Hot 100 题解 · 普通数组篇
算法·leetcode·职场和发展
三8443 小时前
redis防御加固与安全基线
数据库·redis·安全·应急响应·防御
lhldsg3 小时前
全民健身解决方案小程序开发:从0到1的技术实战
java·数据库·需求分析
hqyjzsb4 小时前
零 AI 项目经验,学 Python 转型 AI 的正确顺序是什么?
开发语言·人工智能·python·算法·职场和发展·数据挖掘·数据分析
辰烨chenye4 小时前
LeetCode Hot 100 题解 · 二分篇
java·算法·leetcode
微功夫信息技术4 小时前
分层多智能体强化学习驱动的非急救转运公平 - 效率统一调度系统研究与实践
人工智能·学习·算法·动态规划
IT大白鼠4 小时前
MySQL 分布式集群系列 · 第四篇——实操部署指南:从零搭建生产级 MySQL NDB 集群
数据库·分布式·mysql
IT大白鼠4 小时前
MySQL 分布式集群系列 · 第三篇——核心原理精讲:NDB 自动分片、多主写入与数据同步
数据库·分布式·mysql
Elastic 中国社区官方博客4 小时前
教程:使用 ES|QL 进行威胁狩猎
大数据·运维·数据库·elasticsearch·搜索引擎·全文检索·安全威胁分析