如何在matlab中生成一个具有特定条件的随机二进制矩阵? [英] how to generate a random binary matrix with a specific condition in matlab?

查看:166
本文介绍了如何在matlab中生成一个具有特定条件的随机二进制矩阵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果矩阵A显示G(n,m)矩阵中的一组数目,那么

  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]


解决方案

在对OP的评论中,StackOverflow不是一个代码写入服务。话虽如此,这是一个有趣的问题,我决定作出例外并回答它。



手续费不计入...




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



创建一个 n - by - m 这些 x s留给作为读者的练习(主要是因为它不确定OP是否希望它作为矩阵的单元阵列或4-D逻辑/双数组)。



要理解它的作用,请参阅代码+变量名称中的注释。

  function x = q37055681(G) 
%%输入
如果nargin < 1
G = [1 1 0 0 1
0 1 1 1 0
1 0 1 1 1];
end
%%输入分析:
[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); %<忽略0的
%的RLE结果基于外部定义,每个
%行只有1个组的外部定义(在这种情况下,将其计算在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,[])。';
%%产出的产生:
x =零(大小(G));
for indR = 1:A_ROWS
tokens = cell(sum(A(indR,:)〜= 0),1);
开关numel(令牌)
情况0
%我们不需要做任何事情,整个行都是0.
continue;
case 1
tokens {1} = repelem(true,A(indR,1));
否则
对于indT = 1:numel(令牌)-1
令牌{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]);
%现在我们需要构建一个随机选择的矢量,但是从
%或者标记或zero_tokens中选择一个。
cell_to_pick_from = [ones(1,numel(tokens))zeros(1,numel(zero_tokens))];
choices_order = cell_to_pick_from(randperm(numel(cell_to_pick_from)));
%^这就是随机性出现的地方:
x_line = [];
for indC = 1:numel(choices_order)
如果选择订单(indC)
%如果它是1,从标记中选择
标记=标记{sum(choices_order(1: INDC)== 1)};
else
%如果它是0,则从零中选择
token = zero_tokens {sum(chosen_order(1:indC)== 0)};
结束
x_line = [x_line令牌]; %#ok
end
x(indR,:) = x_line;
结束
结束


If matrix A shows the number of group of ones in G (n,m) matrix like that

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

so the A matrix will be

A = [ 2 1
      3 0
      1 3 ]

Then i want to generate (n,m) random matrix which the ones in this Matrix depend on A in the same order they appear

one solution will be

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

another solution

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

解决方案

As mentions in comments to the OP, StackOverflow is not a code-writing service. Having said that, this was an interesting problem and I decided to make an exception and answer it anyway.

Formalities aside...


I think I have a general solution that can also handle some (all?) edge cases like G with zero rows etc. The code below generates one instance of the x matrix.

Creating an n-by-m array of these xs is left "as an exercise to the reader" (mainly because it's undefined whether OP wants it as a cell array of matrices or a 4-D logical/double array).

To understand what it does, see comments in the code + variable names. I hope it is clear enough (and that I didn't miss any edge cases).

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

这篇关于如何在matlab中生成一个具有特定条件的随机二进制矩阵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆