4

すべての「一意の」整数タプルとそれに対応する多重度を生成する必要があります (私は MATLAB を好みます)。次のk = (k_1, k_2, ..., k_r)2 つの追加条件を満たします。

1. sum(k) = n
2. 0<=k_i<=w_i, where vector w = (w_1,w_2, ..., w_r) contains predefined limits w_i.

「一意の」タプルとは、一意の順序付けられていない要素のセットが含まれていることを意味します (k_1,k_2, ..., k_r)

[t,m] = func(n,w)
t ... matrix of tuples, m .. vector of tuples multiplicities

典型的な問題の次元は次のとおりです。

n ~ 30, n <= sum(w) <= n+10, 5 <= r <= n

(多項式時間アルゴリズムが存在することを願っています!!!)

 Example:

n = 8, w = (2,2,2,2,2), r = length(w) 

[t,m] = func(n,w)

t = 

2 2 2 2 0 

2 2 2 1 1

m = 

5

10

この場合、2 つの「一意の」タプルのみが存在します。

(2,2,2,2,0)多重度 5

同じ要素セットを持つ 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

(2,2,2,1,1)多重度 10 で

同じ要素セットを持つ「同一の」タプルが 10 個ある

 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

助けてくれてありがとう。

4

2 に答える 2

1

これは、Bruno Luong(驚異的なMATLABプログラマー)によって作成された、はるかに優れたアルゴリズムです。

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
于 2013-03-20T20:38:50.230 に答える
1

非常に大雑把な (非常に効果のない) 解決策です。FOR cycle over 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,[2 2 2 2 2])

tup =

     0 2 2 2 2
     1 1 2 2 2


mul =

     5
    10 

または同じケースですが、最初の 2 つの位置の制限が変更されています。

>> [tup mul] = tupmul(8,[1 1 2 2 2])

tup =

     1     1     2     2     2


mul =

    10
于 2013-03-20T14:36:09.583 に答える