Matlab - 生成输入组合及其总和

时间:2015-03-02 18:46:47

标签: matlab matrix combinations combinatorics cartesian-product

我必须创建一个需要3个输入的函数,例如e0e1e2。该函数将有2个输出xy

x将是e0e1e2的组合。 y将是一个列向量,其中包含x列的总和。

创建函数时必须满足以下条件:

  1. 输入e0e1e2每个都有一个数字。
  2. 如果用户未输入输入值,则默认设置为0。
  3. 如果用户未输入任何输入,则应显示未输入任何输入的消息。
  4. 以下是一个例子:

    combination pattern of X (first 3 columns):     pattern for y is the sum of x  
    1 1 1                                           3  
    2 1 1                                           4  
    3 1 1                                           5  
    1 2 1                                           4  
    2 2 1                                           5  
    3 2 1                                           6  
    1 3 1                                           5  
    2 3 1                                           6  
    and so on...                            and so on....  
    

    到目前为止,我只能通过单独显示xy来完成这项工作。

    function [x,y]=create(e0,e1,e2)  
    switch nargin  
    case 2  
        e1=0;  
        e2=0;  
    case 1  
        e2=0;  
    case 0  
        disp('no input')  
    end  
    

    我搜索了我的问题,发现combvec和allcomb应该有所帮助,但我无法弄清楚如何... 请帮助任何答案或提示将是一个很大的帮助。

2 个答案:

答案 0 :(得分:1)

您与allcomb走在了正确的轨道上。您实际上正在寻找cartesian product

[e0, e1, e2] x [e0, e1, e2] x [e0, e1, e2] == [e0, e1, e2]^3.

您不需要allcomb,因为ndgrid可以already do this

让我们从您的代码开始。它有一个bug。基本上case 2case 1会被翻转。

function [x,y] = create(e0,e1,e2)  
switch nargin
case 2
    e1=0; % <- When nargin==2, this value is set, and you overwrite it.
    e2=0;  
case 1  
    e2=0; % <- When nargin==1, e1 must also be set to zero.
case 0  
    disp('no input') % <- use `error` instead of `disp`? If not, use `return` here.
end  

然后,您需要检查提供的数字是否不是矩阵。这可以用类似的东西来实现。 (填空。)

assert(numel(e1)==1 && numel(__)___  && numel(__)___,'Input sizes are incorrect');

要生成您要查找的笛卡尔积[e0, e1, e2] x [e0, e1, e2] x [e0, e1, e2],您可以使用allcomb ndgridthis answer作为内置sets = {[e0,e1,e2], [e0,e1,e2], [e0,e1,e2]}; cartProd1 = allcomb(sets{:}) [x y z] = ndgrid(sets{:}); cartProd2 = [x(:) y(:) z(:)]

cartProd

如果您想要正确的排序,可以交换sum(cartProd,2) 的列。 要沿行生成总和,请使用

{{1}}

答案 1 :(得分:0)

你想要的是排列而不是组合。您列出了2 3 13 2 1不同,但如果您要将其组合在一起,您会认为它们是相同的。因此,我将推荐您参考这篇文章:

How to find all permutations (with repetition) in MATLAB?

我特意要采取Rody Oldenhuis的回答。因此,您可以通过以下方式构建所有可能的排列:

x = unique(nchoosek(repmat([e0 e1 e2], 1, 3), 3), 'rows');

这将使用e0 e1e2创建包含所有可能排列的数组。因此,使用e0 = 1, e1 = 2, e2 = 3的示例,我们得到:

x =

     1     1     1
     1     1     2
     1     1     3
     1     2     1
     1     2     2
     1     2     3
     1     3     1
     1     3     2
     1     3     3
     2     1     1
     2     1     2
     2     1     3
     2     2     1
     2     2     2
     2     2     3
     2     3     1
     2     3     2
     2     3     3
     3     1     1
     3     1     2
     3     1     3
     3     2     1
     3     2     2
     3     2     3
     3     3     1
     3     3     2
     3     3     3

现在最终得到你想要的东西,你只需要总结一下,所以:

y = sum(x, 2)

y =

     3
     4
     5
     4
     5
     6
     5
     6
     7
     4
     5
     6
     5
     6
     7
     6
     7
     8
     5
     6
     7
     6
     7
     8
     7
     8
     9

当用户没有为e0e1和/或e2输入任何内容时,您已经写过要处理的案例,所以您只需要做的是把你的代码,并将我上面写的内容写入你的函数。它应该给你想要的东西。