前一篇文章讲到了德布鲁因序列的递归循环生成,算一下数目,有 22n−1 个,恰好是理论上的理论上的 22n−1−n 的 2n 倍,究其原因,德布鲁因序列是以环的形式展现的,环的不同位置作为序列首,都只能算是同一个序列。因此,只要固定序列的前n位,对后面的部分进行遍历即可。改进了一下代码,如下。
- 同样,编写func函数保存。
function func()
global s l n k data total_num q;
if(size(s,2)<l)
%&&bin2dec(num2str(s(:)))<=(2^l-1)
for p=0:1
s(k)=p;
s=s(1:k);
for j=1:k-n+1
ss{j}=num2str(s(j:j+n-1));
end
if(length(unique(ss))==k-n+1)
if(k+1>l)
s_span=[s s(1:n-1)];
for m=1:l
ss_span{m}=num2str(s_span(m:m+n-1));
end
if(length(unique(ss_span))==l)
fprintf(data,'%s\n',num2str(s));
q=q+1;
disp(['已完成' num2str(q) '/' num2str(total_num) ]);
toc
end
continue;
end
k=k+1;
func();
k=k-1;
end
end
% if(p==1)
% k=k-1;
% end
% if(k>l)
% s_span=[s s(1:n-1)];
% for m=1:l
% ss_span{m}=num2str(s_span(m:m+n-1));
% end
% if(length(unique(ss_span))==l)
% fprintf(data,'%s\n',num2str(s));
% disp(['打印成功']);
% end
% end
end
- 编写主函数,进行递归调用。
clc
clear
tic;
global s l n k data total_num q
q=0;
n=6;
k=n+1;
data=fopen(['D:\DeBruijnSequence_n=' num2str(n) '.txt'],'wt');
l=2^n;
total_num=2^(2^(n-1))/l;
head=0;
head_bin=dec2bin(head,n);
s=str2num(head_bin(:))';
func();
fclose(data);
%toc;
使用matlab自带的计时功能,发现当n=5的时候需要运行三百多秒。对n=6的情况进行了一下时间估计,用我的机器差不多要跑两年的时间。这里是几乎不用任何技巧的一种全局搜索,所以时间是上可能并不是那么理想。