前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >De Bruijin序列与魔术(三)——De Bruijin序列的拓展思考

De Bruijin序列与魔术(三)——De Bruijin序列的拓展思考

作者头像
magic2728
发布2023-09-09 15:11:49
1560
发布2023-09-09 15:11:49
举报
文章被收录于专栏:MatheMagicianMatheMagician

早点关注我,精彩不错过!

在前面的文章中,我们已经介绍完经典DeBruijin序列的原理和魔术,相关内容请戳:

De Bruijin序列与魔术(二)——魔术《De Bruijin序列》

De Bruijin序列与魔术(一)——De Bruijin序列简介

在上一讲中,我们讲到了其中的一个经典作品,《De Bruijin序列魔术》,那是一个数学痕迹十分明显的魔术。这一切都源于一个长度为32的De Bruijin序列,长度上离理想的52张牌还有距离。今天,我们就来尝试从数学理论和魔术需求结合的角度来找找看,有没有更好的序列可以发明和使用。

De Bruijin序列的参数扩展思路

先来回顾一下De Bruijin图。

图1 De Bruijin图

根据De Bruijin序列的定义,D(k, n)中,k为字母表的大小,我们可以取2以外的3,4等值,不过太大的也没必要尝试了,因为这样的De Bruijin序列的长度会瞬间膨胀到远超几十张扑克牌的数量级,没必要也难以用扑克牌的点数进行编码(13也许有奇效可以试试,毕竟和扑克牌的编码范围相等,但试过以后发现,不仅计算量指数增长受不了,因为它是每个原bit的编码数由2变为13,两个位就变成了169,并不满足我们方便地编码一张扑克牌的范围需求,就放弃了);另外n的数值可以取2~10这样的范围,来搜寻可能的其他De Bruijin序列。

但还有一个问题在于,De Bruijin循环序列的搜寻等价于一个汉密尔顿圈问题,是个被证明的np完全问题,是不能够在多项式时间内,确定地判定和找到可行解的。当然有一些启发式算法可以一定程度上缓解这个问题,去搜寻到一些解。但是在这个具体的数学魔术问题上,我们并不需要保证解的完备性,甚至都不需要是个严格的De Bruijin序列,哪怕只是De Bruijin图上的一个小小的子串都行。唯一我们关心的问题是,这种构造方式上的简便性和可拓展性,以及推导出来的序列能否用扑克牌的特征方便地表征编码,以及最后根据这些多进制的数能写出比较合理的公式来解码出对应的扑克牌花色点数来。这一点重要的特征便是,圈的长度最好是13的某倍数,如果是52那就是绝配了,如果是51~55之间的数,也依旧可以细微调整到绝配。

于是这个问题就转化为在一个个De Bruijin图上去找合适大小的圈,如果你愿意放弃可切牌的属性,也就是只是找一条迹的话,那随随便便就能找到。可是这样的序列太多也毫无意义,放弃了可切牌的循环群属性,也增加了魔术操作的难度。

到此,找这个圈最后还剩下一个关键问题,就是如何去写一个方便计算而合理的递推公式,因为只有它易于实现和推导,我们才能够去推导后面的位值,进而去计算整个被观众选择的n张牌的值。

De Bruijin序列的参数扩展公式

参考前面经典De Bruijin魔术里的做法,它其实是取了阶次5以前的值和前面还剩下4个值中的倒数第3个的不进位和。于是我决定从以下角度取泛化这个公式来搜索:

1. 计算式子在k = 2时,我们用的亦或运算有着对0和1两个取值的对称性,即你把0和1对换一下,所有的计算结论会变成其对偶运算同或。但是其他的如且,或等运算,都没有这样的性质。如果你再去构造一个把0 + 1和1 + 0的结果改成不相同的运算的话,那直接交换律都没有了,越来越不优雅;

2. 递推式子的k变为2以上的数时,我们仍然沿用不进位加法的原理,也就是mod加法的模式来推导,这也是我们在k = 2时候用亦或运算而不是同或以及其他bool运算的原因,因为可以和k为更大数值的情况兼容;

3. 我们使用的有且仅有两个前置项来递推后一项的值,一个是2个数时有很好的二元运算的性质,尤其在二进制的时候;另外,增加一个数来加或者减,增加运算量也就增加了魔术的执行难度,只有当这种策略找不到合适的解,没办法了,才会出此下策去尝试;

4. 递推二项中,一定包含一项是n项以前的那个。否则所谓的n阶递推公式实际上就退化为阶次倒退最多的那一个,那也就倒退为实质上n更低的De Bruijin序列的问题中了,没有什么必要;

根据以上经验和数学逻辑的判断,我最终确定了我搜寻De Bruijin图中子圈的公式定为:

a_l = (a_(l - n) + a(l - n + m)) % k,m = 1:(n - 1)

按照这个公式,从[0] * (n - 1) + [1]开始递推,直到发现任何圈即停止,注意这里并不一定要回到起点,选取00001这种开头也是为了保证递推公式有个基本的起点,不至于停着不动。不过,这个方式也是有可能因为起点选择不合适而漏圈的,不过无所谓了,公式已经漏了很多了,我们只需要找到合适的那么1个不错的可行解就够了。

当然这里还可以有不少拓展,比如对值乘以x,然后加上一些常数y等等,再这么做下去,这个玩意就要越来越像Richard Osterlind的序列系列了,甚至那里还只是一阶关联,只不过把花色和点数分开编码使用。那部分内容也十分精彩,甚至可以和这里的内容互相借鉴,我们后面再接着介绍。

那搜寻结果到底如何呢?

我们下回揭晓!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-08-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 MatheMagician 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档