标签(空格分隔): matlab 组合 算法 映射
matlab组合序列的产生,序列与序号的双射函数
1.1 产生组合序列
% 系统的函数
>> nchoosek(1:4, 3)
ans =
1 2 3
1 2 4
1 3 4
2 3 4
% 我写的函数
>> myChoose(4, 3)
ans =
1 2 3
1 2 4
1 3 4
2 3 4
系统的nchoosek()和myChoose()函数都能生成所有组合,但是myChoose()所调用的chooseContinue()函数能够逐个地生成组合序列,这样能节省内存。例如:
>> n=4; r=3;
seq =[1:r]
[seq,loopJudge]=chooseContinue(n,r,seq)
seq =
1 2 3
seq =
1 2 4
loopJudge =
1
>> [seq,loopJudge]=chooseContinue(n,r,seq)
seq =
1 3 4
loopJudge =
1
>> [seq,loopJudge]=chooseContinue(n,r,seq)
seq =
2 3 4
loopJudge =
1
>> [seq,loopJudge]=chooseContinue(n,r,seq)
seq =
[]
loopJudge =
0
1.2 组合序列映射到序数
>> r=3;
>> sequence2num(r,[1 2 3])
ans =
1
>> sequence2num(r,[1 2 4])
ans =
2
>> sequence2num(r,[1 3 4])
ans =
3
>> sequence2num(r,[2 3 4])
ans =
4
1.3 序数映射到组合序列
>> n=4; r=3;
>> seq= num2sequence(n,r,1)
seq =
1 2 3
>> seq= num2sequence(n,r,2)
seq =
1 2 4
>> seq= num2sequence(n,r,3)
seq =
1 3 4
>> seq= num2sequence(n,r,4)
seq =
2 3 4
1.4 源代码
1.4.1 myChoose()
function seqs=myChoose(n,r)
%产生【逐个产生所有组合】的主函数
%% 原创算法
%时间复杂度为O(C(n,r)*r),空间复杂度为O(C(n,r)*r)
%但当只需逐个返回组合序列时(通常满足),空间复杂度为O(r)
%时间:2013/12/28 15:28 姓名:邓能财
%%
seqs=zeros(nchoosek(n,r),r);
loopJudge=true; i=1;
seqs(i,:)=[1:r];
while true
[seqTemp,loopJudge]=chooseContinue(n,r,seqs(i,:));
if loopJudge
seqs(i+1,:)=seqTemp;
i=i+1;
else break; end
end
end
1.4.2 chooseContinue()
function [seq,loopJudge]=chooseContinue(n,r,seq)
% 子函数:产生下一个组合
%时间:2013/12/28 15:28 姓名:邓能财
%找到可以前移的子
i=1;
while i+1<=r
if seq(i+1)==seq(i)+1
i=i+1;
else break; end
end
if i==r && seq(r)==n %当已经达到了最后一个序列
seq=[]; loopJudge=false;
else
seq(i)=seq(i)+1; %第i个前移
for j=1:i-1, seq(j)=j; end %后面的移到初始位置
loopJudge=true;
end
end
1.4.3 sequence2num()
function num= sequence2num(r,seq)
%将【组合序列】映射到C(n,r)的所有组合的【序号】
%% 原创算法
%时间:2013/12/27 22:33 姓名:邓能财
%%
num=0;
for i=r:-1:1
if seq(i)==i, break; end
num=num+nchoosek(seq(i)-1,i);
end
num=num+1;
end
% % % %理论依据:《组合数学》((美国)Richard A.Brualdi)
% % % num=nchoosek(n,r);
% % % seq
% % % for i=1:r
% % % ni=n-seq(i),ri=r-i+1
% % % if ni~=0
% % % num=num-nchoosek(ni,ri);
% % % else
% % % break;
% % % end
% % % end
% % % end 【未用该理论】
1.4.4 num2sequence()
function seq= num2sequence(n,r,num)
%将C(n,r)的某个组合的【序号】映射到【组合序列】
%% 原创算法
%当加上【预计算的C(j,i)矩阵】后,
%时间复杂度为O(n*r),空间复杂度为O(n*r)
%时间:2013/12/28 15:28 姓名:邓能财
%%
seq=[1:r];
lastPoint=n;
num=num-1;
for i=r:-1:1
% '##loop i'
if num==0, break; end
for j=lastPoint:-1:1
% j_i=[j,i] % ( i==j ||
if num<nchoosek(j,i) && num>=nchoosek(j-1,i)
seq(i)=j; lastPoint=j-1; break;
end
end
num=num-nchoosek(j-1,i);
end
end
联系作者 definedone@163.com
end