MATLAB 整数拆分程序 转载

MATLAB 整数拆分程序 转载


转载本文请联系原作者获取授权,同时请注明本文来自黄川科学网博客。
链接地址:http://blog.sciencenet.cn/blog-567861-586909.html

“整数拆分MATLAB代码”中给出了一种列出所有拆分数组的算法。后来在解决一个统计问题时编写了些接口程序,例如:对数字45拆分,而数组中元素为整数,取值 4到13之间等。下面的这几个就是关于类似问题的接口程序。

  1. 已知数字A,求其由xi∈[a,b],i=1…dim的拆分组合。

function H=p_l(dim_m,sum_m,Max,Min) %Max=b;Min=a;sum_m=A;dim_m=dim

if Mindim_m>sum_m||Maxdim_m<sum_m

H=[];

else

p=Max-Min;

n=sum_m-dim_m*Min;

s={[0,1]};

for i=2:n %when n>1

k=size(s,2);

w={};

for j=1:k

    if (s{j}(end)<s{j}(end-1))&&(s{j}(end)<p)

        w{end+1}=s{j};

        w{end}(end)=w{end}(end)+1;

    end

    if size(s{j},2)<dim_m+1

        w{end+1}=s{j};

        w{end}(end+1)=1;

    end

end

if(i<=p)

w{end+1}=[0,i];

end

s=w;

end

if dim_m*Min==sum_m %(1)

s={[0]};

end

H=ones(size(s,2),dim_m)*Min;

for i=1:size(s,2)

H(i,1:size(s{i},2)-1)=s{i}(2:end)+Min;

end

end

end

(1)唯一的种情况,当Min*dim_m=sum_m时,程序执行后s原本应为空,但由于初始定义了s={[0,1]},将出现BUG,然而初始定义s={[0,1]}可使程序简便得多,所以在这种情况下必须强制置0来避免这种错误。

s={[0,1]}与w{end+1}=[0,i],可以取消掉主循环中j<k的判断,size(s{j},2)<dim_m+1与(s{j}(end)<p)用来实现拆分数组元素个数和大小的限定。

例如:5个数,最大为7,最小为3,其和为18的组合:

H=p_l(5,18,7,3)

H =

 4     4     4     3     3

 5     4     3     3     3

 6     3     3     3     3

p_l函数是“整数拆分MATLAB代码”中的psn函数扩展改写。

function s=psn(n)

s={1};

w=s;

for i=2:n %when n>1

k=size(s,2);

for j=1:k

    w{j}(end+1)=1;

    if (j<k)&&(s{j}(end)<s{j}(end-1))

        w{end+1}=s{j};

        w{end}(end)=w{end}(end)+1;

    end

end

w{end+1}=i;

s=w;

end

end

  1. 拆分数的递归形式。

设f(A,b)为A的所有以xi∈[1,b],i=1、2、3…为元素的拆分数,则f(A,b)=f(A,b-1)+f(A-b,b),也就是欧拉分割函数(证明很直观,这儿就忽略了)。若是只须求拆分数,使用分割函数会比psn函数快很多,但分割函数不能列出拆分数组。

function s=di_Euler(n,k) %n=A; k=b;

if (n0)||(k0) %(2)

s=(n==0);    

elseif(n<k)

s=di_Euler(n,n);

else

s=di_Euler(n,k-1)+di_Euler(n-k,k);

end

end

re= di_Euler(18,18)

re=

385

re=size(psn(18),2)

re =

385

re=size(p_l(18,18,18,0),1)

re =

385

(2)f(0,0)=1,由0组合成0,有一种方式。f(0,3)由小于3的数组合成0有一种方式。f(x,0)=0,当x≠0时,不存在组合。

  1. 已知数字A,求其由xi∈[a,b],i=1、2、3…的拆分组合。

function L=psnab(sum_m,Max,Min)

%Max=b;Min=a;sum_m=A;

dim_min=ceil(sum_m/Max);

dim_max=floor(sum_m/Min);

P={};

for i=dim_min:dim_max

tmp=p_l(i,sum_m,Max,Min);

if size(tmp,2)>0

    P{end+1}=tmp;

end

end

L=[];

for i=1:size(P,2)

L=[L;[P{i},zeros(size(P{i},1),size(P{end},2)-size(P{i},2))]];

end

end

例:

L=psnab(13,13,5)

L =

13     0

 7     6

 8     5  

暂时就这几个接口函数,以后遇到应用再补充。虽然应用中没发现其他的问题,但程序也许还存在BUG,而且效率也不算多好。谁有更好的方法,或者程序编写的建议,不吝赐教啊。

转载本文请联系原作者获取授权,同时请注明本文来自黄川科学网博客。
链接地址:http://blog.sciencenet.cn/blog-567861-586909.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值