【问题标题】:Generating a Matrix from a given vector从给定向量生成矩阵
【发布时间】:2020-12-12 20:01:06
【问题描述】:

我试图在 Matlab 中生成一个特定类型的矩阵。

我需要根据以下规则针对特定类型的数据进行修改:

  • 首先我必须选择一个等级g(假设最多6个)然后我必须选择每行元素的数量n(最多18个);

  • 这些数字是等级g的特定多项式的幂;

  • 矩阵中每行的总和不允许大于选择的g等级;

  • 每行最大的元素是选中的g

对于g = 2n = 2,矩阵将如下所示:

A = [0 0; 
     0 1; 
     1 0; 
     0 2; 
     2 0; 
     1 1]

对于g = 2n = 3,矩阵将如下所示:

A = [0 0 0; 
     0 0 1; 
     0 0 2; 
     0 1 0; 
     0 2 0; 
     1 0 0; 
     2 0 0; 
     0 1 1; 
     1 0 1;
     1 1 0]

如何生成数组元素的所有可能组合?

Ex : given v = [0 1 2];

Result = [0 0 0;
          0 0 1;
          0 1 0;
          0 1 1;
          1 0 0;
          1 0 1;
          1 1 0;
          1 1 1;
          0 0 2;
          0 2 0;
          2 0 0;
          2 0 1;
          2 1 1;
          2 1 2;
            ...]
and so on...

我已经用permsnchoosekrepelemrepmatfor-loopsuniquematrix concatenations 尝试了这个,但我无法找到和算法。

【问题讨论】:

    标签: matlab matrix vector


    【解决方案1】:

    您可以先通过重复和重新排列生成[0..g] 的所有n 排列,然后选择允许的组合:

    % all n permutations of [0..g] (with repetition and rearrangement)
    powers = unique(nchoosek(repmat(0:g, 1, n), n), 'row');
    % allowed set of powers
    powers = powers(sum(powers, 2) <= g, :);
    

    正如我在 cmets 中已经说过的,上面的代码在时间和内存上都非常低效。例如,当我为g=6n=9 运行它时,MATLAB 给出以下错误:

    使用零时出错请求的 23667689815x9 (1587.0GB) 数组超出 最大数组大小首选项。
    ...

    要减少内存消耗,您可以执行以下操作:

    % all n permutations of [0..g] (with repetition)
    gPerms = nmultichoosek(0:g, n);
    % allowed set of powers
    allowed = gPerms(sum(gPerms, 2) <= g, :);
    % all permutations of [1..n] (no repetition)
    nPerms = perms(1:n);
    % all n permutations of [0..g] (with repetition and rearrangement)
    arranges = arrayfun(@(i) allowed(:, nPerms(i, :)), ...
        1:size(nPerms, 1), 'UniformOutput', false)';
    powers = cell2mat(arranges);
    % unique set of permutations
    powers = unique(powers, 'rows');
    

    在上面的代码中,使用@knedlsepp's implementation 生成第一个具有g 重复的n 排列。过滤后仅保留其总和小于或等于g 的组合。在下一步中,计算这些组合的所有重排。在这里找到 g=6n=9 案例的 5005 组合仍然需要超过 13 秒。

    【讨论】:

    • 那是完美的。非常感谢你,我已经尝试了一整天,但没有成功。 200 多行代码转换为 2 。非常感谢
    • @netseg 我很高兴它有帮助。请注意,这非常耗费时间和内存。在某种程度上,您甚至无法接近g=6n=18。恐怕您将不得不返回所有这 200 行以获得这些值。
    • @netseg 更新了我的答案以获得更高效的内存实现。
    • 谢谢你,这更好。对于我的需要,我认为第一个就足够了。无论如何,对于我更大的项目,我会使用第二个。再次感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多