De Bruijn序列的matlab暴力生成

来源:互联网 发布:jquery get json数据 编辑:程序博客网 时间:2024/06/07 06:06

问题:能否构造一个长度为2的n次方的二进制环状串,使得二进制环状串中总共2的n次方个长为n的不同截断作为2的n次方个长为n的二进制串来说互不相同。
1946年,荷兰数学家De Bruijn解决了这个问题。
这种序列,就是De Bruijn序列。
注意到,00010111的所有长度为3的子序列为000,001,010,101,011,111,110,100,正好构成了{1,0}3 的所有组合。这就是这种序列的特性。
De Bruijn序列用途很广泛,我就不介绍了。如密码学。
关于序列的生成,网上提供了很多快速算法,如k 元 de Bruijn 序列的反馈函数的一个升级算法,生成数法、算子法、并圈法等等等等,不一而同。作为一条懒虫,并不想去理解太多算法,所以,我决定了使用机器暴力遍历生成。简单的想法是,把所有的可能序列统统列出来,然后进行一个一个判断。
我写的第一段代码:

clearclcclose% n=5;for n=1:4l=2^n;f=dec2bin(0:(2^l-1),l);disp('已生成所有母序列!');data=fopen(['D:\De_Bruijn_n=' num2str(n) '.txt'],'wt');lf=length(f)for i=1:lf    disp(['正在判定第' num2str(i) '/' num2str(lf) '个母列是否满足条件']);    s0=f(i,1:l);    s=strcat(s0,s0(1:n-1));    for j=1:l    ss{j}=s(j:j+n-1);    end    if(length(unique(ss))==l)    fprintf(data,'%s\n',s0);    endendfclose(data);end

然而,当n到5的时候就提示内存不够了。究其原因,原来是矩阵规模太大,于是,针对n比较大的情况,我把代码改成了这样:

clearclcclosen=5;l=2^n;data=fopen(['D:\De_Bruijn_n=' num2str(n) '.txt'],'wt');for f=0:(2^l-1)    f_bin=dec2bin(f,l);    disp(['正在判定第' num2str(f) '/' num2str(2^l) '个母列是否满足条件']);    s=strcat(f_bin,f_bin(1:n-1));    for j=1:l    ss{j}=s(j:j+n-1);    end    if(length(unique(ss))==l)    fprintf(data,'%s\n',f_bin);    endendfclose(data);

没有内存不足的问题了。然而,更为悲哀的是,运行速度。粗略估计了一下,即使是开着笔记本不眠不休地跑,也要跑120个小时左右。
这里写图片描述
事实上,如果在序列的前几个子列已经重复了,后面部分的循环就没必要做了。根据这个思想,我决定再写一段代码,大大减少需要判断的序列。将在下一篇博文中和大家分享。

最开始的想法是,从2n个子列入手,进行拼接生成序列。子列可以进行分层,一类子列只能接在某一类子列后面,而放在另一类子列前面。使用类似链表的方式进行组合成串进而判断。但是貌似比较难搞,决定还是从母列入手。敬请期待。

0 0
原创粉丝点击