对matlab中的所有子集求和

时间:2015-02-12 01:28:03

标签: algorithm matlab

给出一个数字' c'和一个数字列表'我试图生成我可以拥有的所有c和数字中的任何子集。 例如。 (1,[2,4,8]),我应该生成(注意我们应该总是有一个c) [1,3,5,9,7,11,13,15]

我写了下面的代码,但并不是所有的总和都出现了。有什么问题?

function result = allsums(c, numbers)
    if isempty(numbers)
        result = [];
    else
        [nr n_numbers] = size(numbers);
        for i = 1:n_numbers
            result = cat(2, c+numbers(i), allsums(c, cat(2,numbers(1:i-1),numbers(i+1:end))));
        end
    end

result = cat(2, result, c+sum(numbers,2));
end

3 个答案:

答案 0 :(得分:3)

这可能是一种方法 -

%// Input array and scalar
numbers = [2,4,8] 
c = 1;

%// Generate all sums for all combinations with nchoosek; then add up with c
combsums = arrayfun(@(n) sum(nchoosek(numbers,n),2),1:numel(numbers),'Uni',0)
result = [c ; c+vertcat(combsums{:})]

代码运行 -

result =
     1
     3
     5
     9
     7
    11
    13
    15

答案 1 :(得分:2)

错误的是:

result = cat(2, sums, c+sum(numbers,2));

因为你在没有输入参数的情况下调用了函数sums,而你用2个输入参数编写了函数。

更新:

如果length(numbers)小于15(http://www.mathworks.com/help/matlab/ref/nchoosek.html),您可以尝试这样nchoosek

function result = sums(c, numbers)
  result = [];
  if ~isempty(numbers)
    [nr n_numbers] = size(numbers);
    result = c;
    for i = 1:n_numbers
      combi = nchoosek(numbers, i);
      for j = 1:size(combi, 1)
        result(end+1) = c + sum(combi(j,:));
      end
    end
  end
  result = unique(result);
end

p / s:只是一个非常快速的例子,你可以尝试优化代码,我不确定使用像你这样的递归更好还是使用Matlab的内置函数更好......

答案 2 :(得分:2)

单线解决方案怎么样?

c = 1; %// number 
S = [2 4 8]; %// set

result = unique(c+S*(dec2bin(0:2^numel(S)-1).'-'0'));

解释:此处的密钥为dec2bin(0:2^numel(S)-1).'-'0',它会生成0 - 1模式,指示集合S中的哪些元素已添加。在示例中,这是

 0     0     0     0     1     1     1     1
 0     0     1     1     0     0     1     1
 0     1     0     1     0     1     0     1

每列对应S的不同子集。矩阵乘以S然后给出每个子集的总和。