我有一个阵列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
但是我没能按照我想要的方式将它们组合在一起。
目标:
从B中添加可能的组合,以便它们的总和小于2000?
约束1:
B
中每行的一个值。 例如, NOT 可接受:[1 2 20] [2 20 30]
这是正确之一:[1 20 100] [3 200 3000]
约束2: - 答案应仅存储在单元格V中的一列中(在上面的代码中初始化)。
单元格的输出应该与我目前的输出类似:
V =
[ 100]
[ 300]
[ 200]
[2x1 double]
[2x1 double]
[2x1 double]
[3x1 double]
答案 0 :(得分:1)
稍微更改了您的代码并在下面添加了测试 - 如果V未更改 - >没有组合 - &gt;显示出来。编辑为允许将其保存到单元格数组V
中,同时构造一个字符串进行打印。
此代码考虑B中三个元素的每个组合,其中每个元素来自不同的列。
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
答案 1 :(得分: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
也许这不是最有效的解决方案,但它很简短且有效。