MATLAB 整数拆分程序 转载
转载本文请联系原作者获取授权,同时请注明本文来自黄川科学网博客。
链接地址:http://blog.sciencenet.cn/blog-567861-586909.html
“整数拆分MATLAB代码”中给出了一种列出所有拆分数组的算法。后来在解决一个统计问题时编写了些接口程序,例如:对数字45拆分,而数组中元素为整数,取值 4到13之间等。下面的这几个就是关于类似问题的接口程序。
- 已知数字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
- 拆分数的递归形式。
设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时,不存在组合。
- 已知数字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