您的位置:首页 > 编程语言 > MATLAB

De Bruijn序列的matlab暴力生成

2016-04-08 23:38 525 查看
问题:能否构造一个长度为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 序列的反馈函数的一个升级算法,生成数法、算子法、并圈法等等等等,不一而同。作为一条懒虫,并不想去理解太多算法,所以,我决定了使用机器暴力遍历生成。简单的想法是,把所有的可能序列统统列出来,然后进行一个一个判断。

我写的第一段代码:

clear
clc
close
% n=5;
for n=1:4
l=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);
end
end
fclose(data);
end


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

clear
clc
close
n=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);
end
end
fclose(data);


没有内存不足的问题了。然而,更为悲哀的是,运行速度。粗略估计了一下,即使是开着笔记本不眠不休地跑,也要跑120个小时左右。



事实上,如果在序列的前几个子列已经重复了,后面部分的循环就没必要做了。根据这个思想,我决定再写一段代码,大大减少需要判断的序列。将在下一篇博文中和大家分享。

最开始的想法是,从2n个子列入手,进行拼接生成序列。子列可以进行分层,一类子列只能接在某一类子列后面,而放在另一类子列前面。使用类似链表的方式进行组合成串进而判断。但是貌似比较难搞,决定还是从母列入手。敬请期待。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: