【问题标题】:how to generate a random binary matrix with a specific condition in matlab?如何在matlab中生成具有特定条件的随机二进制矩阵?
【发布时间】:2016-08-31 12:59:41
【问题描述】:

如果矩阵A像这样显示G(n,m)矩阵中1的组数

G = [ 1 1 0 0 1 
      0 1 1 1 0
      1 0 1 1 1 ] 

所以 A 矩阵将是

A = [ 2 1
      3 0
      1 3 ]

然后我想生成 (n,m) 随机矩阵,该矩阵中的矩阵以它们出现的相同顺序依赖于 A

一个解决方案将是

x = [ 0 1 1 0 1
      0 0 1 1 1
      1 0 1 1 1 ]

另一种解决方案

x = [ 1 1 0 1 0
      1 1 1 0 0
      1 0 1 1 1 ]

【问题讨论】:

  • 为什么会有R标签?
  • 输入是什么?想要的输出是什么?到目前为止,您尝试过什么?
  • @lmo 也许出于同样的原因,它有 matlab 标签 - R、Matlab 和 Octave 常用于处理矩阵。
  • 我看不到您如何从AG 或反之亦然(以及它们与x 的关系)。您能否提供一个详细分步算法来从输入生成输出?编辑:没关系,我现在看到 A 在 G 的行中计数 连续 个。
  • @Crowley 这是否意味着我们应该包含julia-langeigenwolfram-mathematica 以确保安全?不,标签不是用来试图获得可见性,它们是用来识别这个特定问题的内容。搜索如何在 R 中生成随机二进制矩阵的人不会希望看到专门针对 MATLAB 的问题以及专门为 MATLAB 制作的答案。

标签: matlab function matrix random


【解决方案1】:

正如 cmets 对 OP 所述,StackOverflow 不是代码编写服务。话虽如此,这是一个有趣的问题,我决定破例回答。

除了手续...


我想我有一个通用的解决方案,它还可以处理一些(全部?)边缘情况,例如零行的G 等。下面的代码生成x 矩阵的一个实例。

创建这些xs 的n-by-m 数组“作为对读者的练习”(主要是因为 OP 是否希望将其作为矩阵单元数组或 4- D 逻辑/双数组)。

要了解它的作用,请参阅代码中的 cmets + 变量名。我希望它足够清楚(并且我没有错过任何边缘情况)。

function x = q37055681(G)
  %% Input
  if nargin < 1
    G = [ 1 1 0 0 1
          0 1 1 1 0
          1 0 1 1 1 ];
  end
  %% Input analysis:
  [A_ROWS,OUT_COLS] = size(G);
  transitions = find(diff(padarray(G.',1,false,'both').',1,2).');
  tr_per_ln = hist(ceil(transitions/(size(G,2)+1)),size(G,1))/2;
  A_COLS = max(tr_per_ln);
  missing_trans_per_line = A_COLS - tr_per_ln;
  groups_of_ones = diff(reshape(transitions,2,[]),1,1); % < result of RLE which ignores 0's
  % Count "fixing" based on the external definition of what to do with only 1 group per 
  % line (in this case, count it in the first element of A): 
  insrt = @(what, into, where) cat(2, into(1:where-1), what, into(where:end));
  for indZ = 1:sum(missing_trans_per_line(:))
    next_incomplete = find(missing_trans_per_line,1);
    groups_of_ones = insrt(0, groups_of_ones, A_COLS*next_incomplete-...
                                (missing_trans_per_line(next_incomplete)-1));
    missing_trans_per_line(next_incomplete) = missing_trans_per_line(next_incomplete)-1;
  end
  A = reshape(groups_of_ones,A_COLS,[]).';
  %% Generation of output:
  x = zeros(size(G));
  for indR = 1:A_ROWS
    tokens = cell(sum(A(indR,:)~=0),1);
    switch numel(tokens)
      case 0
        % we don't need to do anything, the entire line is 0.
        continue;
      case 1
        tokens{1} = repelem(true,A(indR,1));
      otherwise
        for indT = 1:numel(tokens)-1
          tokens{indT} = [repelem(true,A(indR,indT)) 0];
        end
        tokens{end} = repelem(true,A(indR,find(A(indR,:),1,'last')));
    end
    zero_tokens = repmat({0},[OUT_COLS-sum(A(indR,:))-(numel(tokens)-1),1]);  
    % Now we need to build a vector that selects randomly but SEQUENTIALLY from 
    % EITHER tokens or zero_tokens. 
    cell_to_pick_from = [ones(1,numel(tokens)) zeros(1,numel(zero_tokens))];
    choosing_order = cell_to_pick_from(randperm(numel(cell_to_pick_from)));
    % ^ Here's where the randomness comes in:
    x_line = [];
    for indC = 1:numel(choosing_order)
      if choosing_order(indC)
        % if it's 1, choose from "tokens"
        token = tokens{sum(choosing_order(1:indC)==1)};
      else
        % if it's 0, choose from "zeros"
        token = zero_tokens{sum(choosing_order(1:indC)==0)};
      end
      x_line = [x_line token]; %#ok
    end
    x(indR,:) = x_line;
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-26
    • 2017-04-30
    • 1970-01-01
    • 2018-10-26
    • 2012-11-21
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多