1

私は次の配列Bを持っています:

B=[1 2 3; 10 20 30 ; 100 200 300 ; 1000 2000 3000]

そのような

B =

           1           2           3
          10          20          30
         100         200         300
        1000        2000        3000

私は次のコードを使用して、特定の値(制約)を下回るこれらの変数間の可能な組み合わせを見つけています-この場合は2000:

A=[123; 323; 12 ; 421]
SA=sum(A)
V=cell(length(B),1);
n=1;
for k = 1:length(B)
    for idx = nchoosek(1:length(B), k)'
        B_subset = B(idx);
        if (SA + sum(B_subset) <= 2000)
            V(n)={B_subset(:)}; %store them in a cell
            n=n+1;
        end
    end
end

しかし、私はそれらを以下のように組み合わせることができませんでした。


目的 :

それらの合計が2000未満になるようにSAで追加されるBからの可能な組み合わせを見つけますか?


制約1:

  • 配列の各行から一B度に使用できる値は1つだけです。

たとえば、これは受け入れられません:[1 2 20] [2 20 30]
これは正しいものです:[1 20 100] [3 200 3000]


制約2:-回答は、セルVの1つの列にのみ格納する必要があります(上記のコードで初期化されています)。

セルには、現在持っているものと同様の出力が必要です。

V = 

    [       100]
    [       300]
    [       200]
    [2x1 double]
    [2x1 double]
    [2x1 double]
    [3x1 double]
4

2 に答える 2

1

ここで、この修正でうまくいくはずです。

SA = sum(A);
V = cell(numel(B), 1);                  % // Changed 'length' to 'numel'
n = 1;
for k = 1:size(B, 1)                    % // Changed 'length' to 'size'
    for idx = nchoosek(1:numel(B), k)'  %'// Changed 'length' to 'numel'

        %// Ignore the combination if there are two elements from the same row
        rows = mod(idx, size(B, 1));
        if ~isequal(rows, unique(rows))
            continue
        end

        B_subset = B(idx);
        if (SA + sum(B_subset) <= 2000)
            V(n) = {B_subset(:)};
            n = n + 1;
        end
    end
end

おそらく、これは最も効率的なソリューションではありませんが、短く、機能します。

于 2013-03-07T19:34:12.737 に答える
1

コードを少し変更し、以下にテストを追加しました - V が変更されていない場合 -> 組み合わせがなかった -> それを表示します。Vそれをセル配列に保存し、同時に印刷用の文字列を作成できるように編集しました。

このコードは、B の 3 つの要素のすべての組み合わせを考慮します。ここで、各要素は異なる列からのものです。

V=cell(length(B),1);
A=[123; 323; 12 ; 421];
SA=sum(A);
S = 'possible combinations :';
n = 1
for ii=1:4
    for jj=1:4
        if jj == ii
            continue
        end
        for kk=1:4
            if or(kk == jj,kk == ii)
                continue
            end
            B_subset = [B(ii,1), B(jj,2), B(kk,3)];
            if (SA + sum(B_subset) <= 2000)
                S = [S, ' ', mat2str(B_subset)];
                V{n} = B_subset;
                n += 1;
            end
        end
    end
end

if V == 'possible combinations :'
    disp('No possible combinations found')
else
    disp(S)
end

編集:質問の新しい部分に回答を追加します。最も内側のループでは、含まれる行のさまざまな組み合わせが計算されます。

V = {}
for ii=1:3
    for jj=1:3
        for kk=1:3
            for ll = 1:3
                rows = [ii, jj, kk, ll]
                if isequal(rows, unique(rows))
                    % loop for turning off individual elements
                    result = [B(1,ii), B(2,jj), B(3,kk), B(4,ll)]
                    for mm = 0:1:15
                        % make a binary string - will loop through all combinations of zeros and ones
                        str1 = dec2bin(mm,4)
                        mask = zeros(1,4)
                        for nn = 1:4 % make a numeric vector
                            mask(nn) = str2num(str1(nn))
                        end
                        masked_result = mask.*result
                        V = [V {masked_result}]
                    end
                end
            end
        end
    end
end
于 2013-03-07T18:37:29.367 に答える