特定元组生成和计数(matlab)
我需要生成(我更喜欢MATLAB)所有“唯一”整数元组特定元组生成和计数(matlab),matlab,tuples,combinatorics,multiple-conditions,Matlab,Tuples,Combinatorics,Multiple Conditions,我需要生成(我更喜欢MATLAB)所有“唯一”整数元组k=(k_1,k_2,…,k_r) 其相应的多重性,满足两个附加条件: 1. sum(k) = n 2. 0<=k_i<=w_i, where vector w = (w_1,w_2, ..., w_r) contains predefined limits w_i. 典型的问题维度是: n ~ 30, n <= sum(w) <= n+10, 5 <= r <= n 在这种情况下,仅存在两个“唯一”元
k=(k_1,k_2,…,k_r)
其相应的多重性,满足两个附加条件:
1. sum(k) = n
2. 0<=k_i<=w_i, where vector w = (w_1,w_2, ..., w_r) contains predefined limits w_i.
典型的问题维度是:
n ~ 30, n <= sum(w) <= n+10, 5 <= r <= n
在这种情况下,仅存在两个“唯一”元组:
多重数为5的(2,2,2,2,0)
有5个具有相同元素集的“相同”元组
0 2 2 2 2
2 0 2 2 2
2 2 0 2 2
2 2 2 0 2
2 2 2 2 0
1 1 2 2 2
1 2 1 2 2
1 2 2 1 2
1 2 2 2 1
2 1 1 2 2
2 1 2 1 2
2 1 2 2 1
2 2 1 1 2
2 2 1 2 1
2 2 2 1 1
及
多重数为10的(2,2,2,1,1)
有10个具有相同元素集的“相同”元组
0 2 2 2 2
2 0 2 2 2
2 2 0 2 2
2 2 2 0 2
2 2 2 2 0
1 1 2 2 2
1 2 1 2 2
1 2 2 1 2
1 2 2 2 1
2 1 1 2 2
2 1 2 1 2
2 1 2 2 1
2 2 1 1 2
2 2 1 2 1
2 2 2 1 1
提前感谢您的帮助。非常粗糙(非常无效)的解决方案。对于循环超过2^nvec-1(nvec=r*maxw)的测试样本和变量res的存储是非常糟糕的事情
此解决方案基于以下内容
还有更有效的方法吗?
function [tup,mul] = tupmul(n,w)
r = length(w);
maxw = max(w);
w = repmat(w,1,maxw+1);
vec = 0:maxw;
vec = repmat(vec',1,r);
vec = reshape(vec',1,r*(maxw+1));
nvec = length(vec);
res = [];
for i = 1:(2^nvec - 1)
ndx = dec2bin(i,nvec) == '1';
if sum(vec(ndx)) == n && all(vec(ndx)<=w(ndx)) && length(vec(ndx))==r
res = [res; vec(ndx)];
end
end
tup = unique(res,'rows');
ntup = size(tup,1);
mul = zeros(ntup,1);
for i=1:ntup
mul(i) = size(unique(perms(tup(i,:)),'rows'),1);
end
end
或相同情况,但前两个位置的限值发生变化:
>> [tup mul] = tupmul(8,[1 1 2 2 2])
tup =
1 1 2 2 2
mul =
10
这是一个更好的算法,由Bruno Luong(杰出的MATLAB程序员)创建:
函数[t,m,v]=tupmul(n,w)
v=tmr(长度(w),n,w);
t=排序(v,2);
[t,~,J]=唯一(t,'rows');
m=accumarray(J(:),1);
结束%tupmul
功能v=tmr(p、n、w、水头)
如果p==1
如果n显然我的独特的
/perms
方法确实对您有所帮助?:-)对但多重性可以更有效地计算。。。见下一个答案[tup mul]=tupmul(8[1,2])产生错误的结果,应该是mul=1是。。。真理的苦果:)
>> [tup mul] = tupmul(8,[1 1 2 2 2])
tup =
1 1 2 2 2
mul =
10
function [t, m, v] = tupmul(n, w)
v = tmr(length(w), n, w);
t = sort(v,2);
[t,~,J] = unique(t,'rows');
m = accumarray(J(:),1);
end % tupmul
function v = tmr(p, n, w, head)
if p==1
if n <= w(end)
v = n;
else
v = zeros(0,1);
end
else
jmax = min(n,w(end-p+1));
v = cell2mat(arrayfun(@(j) tmr(p-1, n-j, w, j), (0:jmax)', ...
'UniformOutput', false));
end
if nargin>=4 % add a head column
v = [head+zeros(size(v,1),1,class(head)) v];
end
end %tmr