【问题标题】:Matlab - generating combinations of input and their sumMatlab - 生成输入及其总和的组合
【发布时间】:2015-05-03 05:48:12
【问题描述】:

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

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

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

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

这是一个例子:

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 应该有帮助,但我不知道如何.. 请帮助任何答案或提示将是一个很大的帮助。

【问题讨论】:

    标签: matlab matrix combinations combinatorics cartesian-product


    【解决方案1】:

    您与allcomb 走在正确的轨道上。你其实是在找cartesian product:

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

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

    让我们从您的代码开始。它有一个错误。基本上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],您可以使用this answer 来生成allcomb,或者使用this answer 来生成内置的ndgrid

    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)
    

    【讨论】:

    • 非常感谢。你的回答对我帮助很大。现在我清楚地明白我做错了什么。
    • @Frankwiene:我的荣幸!
    【解决方案2】:

    你想要的是排列而不是组合。您列出了 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 输入任何内容时,您已经编写了要处理的案例,因此您所要做的就是获取您的代码,然后拼凑我的代码上面写到你的函数中。它应该给你想要的。

    【讨论】:

    • 非常感谢您的回答。这是一个很大的帮助。
    猜你喜欢
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多