matlab组合序列的产生,序列与序号的双射函数

5 篇文章 0 订阅
2 篇文章 0 订阅

标签(空格分隔): 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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值