【问题标题】:Generate random 2D matrix with unique rows in octave/matlab在 octave/matlab 中生成具有唯一行的随机二维矩阵
【发布时间】:2015-05-03 10:36:42
【问题描述】:

我想生成一个 2D 矩阵 (1000x3),其随机值范围为 1 到 10 倍频程。使用 randi(10,1000,3) 将生成具有重复行值的矩阵。但我想生成唯一(不重复的)行。有什么办法,我可以做到吗?

【问题讨论】:

    标签: matlab octave


    【解决方案1】:

    您可以轻松地做到这一点,方法是让笛卡尔积创建所有可能性并对数组进行如下洗牌。要创建笛卡尔积,您将需要我的自定义 cartprod.m function,它会生成 cartesian product

    C = cartprod(1:10,1:10,1:10);
    

    接下来的行将洗牌笛卡尔积C

    S = C(randperm( size(C,1) ),:);
    

    注意事项:

    • S 中的每一行都是唯一的,您可以验证 size( unique( S ) ) == 1000
    • 请注意,此代码适用于 Matlab 2015a。我没有在 Octave 中测试过它,这似乎是 OP 正在使用的。我被告知语法几乎相同。

    【讨论】:

    • 我想在同一个矩阵(1000x3)上工作。当我使用 randperm 时,行每次都在变化。有什么方法可以让我只生成一次该矩阵然后对其进行处理?
    • @Cherry Awesome :) 好吧,它都存储在一个变量 S 中,所以一旦它在内存中,就可以使用它?如果你想存储随机性,你也可以像这样存储它R = randperm( size(C,1) );,并将我上面的代码替换为R。这能回答你的问题吗?
    • @Cherry 另外,因为我没有 Octave,你能告诉我我的自定义 cartprod 函数是否真的在那里工作吗?如果是这样,我也会将它用于其他人的未来 Octave 答案!
    • 您的 cartprod 函数在 Octave 中运行良好。再次感谢您的帮助:)
    • @Cherry Sweet!随时:D
    【解决方案2】:

    您可以使用以下函数生成从 1 到 10 绘制的所有可能的三项序列,并带有替换:

    function result = nchoosek_replacement(n, k)
    
        %// Edge cases: just return an empty matrix 
        if k < 1 || n < 1 || k >= n
            result = [];
            return
        end
    
        reps = n^(k-1);
        result = zeros(n^k, k);
        cur_col = repmat(1:n, reps, 1);
        result(:,1) = cur_col(:);
    
        %// Base case: when k is 1, just return the
        %// fully populated matrix 'result'
        if k == 1
            return
        end
    
        %// Recursively generate a matrix that will
        %// be used to populate columns 2:end
        next = nchoosek_replacement(n, k-1);
    
        %// Repeatedly use the matrix above to
        %// populate the matrix 'result'
        for i = 1:n
            cur_range = (i-1)*reps+1:i*reps;
            result(cur_range, 2:end) = next;
        end
    
    end 
    

    定义此函数后,您现在可以生成所有可能的序列。在这种情况下,正好有 1000 个,所以它们可以简单地用randperm 打乱。一种更通用的方法是使用 randsample 从它们中采样,如果需要,这也允许使用更小的矩阵:

    max_value = 10;
    row_size = 3;    
    num_rows = 1000;
    
    possible = nchoosek_replacement(max_value, row_size);
    indices = randsample(size(possible, 1), num_rows);
    data = possible(indices, :);
    

    【讨论】:

    • Error: File: nchoosek_replacement.m Line: 11 Column: 16 ()-indexing must appear last in an index expression.
    • 即使在解决了这个问题和任何后续问题之后,它也不像我的回答那样简洁或合乎逻辑。此外,您不必删除您的答案,如果您编辑了答案,我会不赞成:)
    • 我在 Matlab 2015a 中运行它。我从来没有见过这样的工作repmat(1:n, reps, 1)(:)你不能在函数调用后选择所有元素,否则我的代码库中的代码会少得多:P
    • 哦。 OP 在八度音阶中工作,这很好用(至少对我来说),但我会让它更通用。
    猜你喜欢
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 2020-04-20
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 2013-12-14
    相关资源
    最近更新 更多