具有频率约束的Matlab伪随​​机整数

时间:2017-06-22 11:46:33

标签: matlab random integer

我对MATLAB比较陌生,我需要设计一个200x1矩阵,它填充随机整数,可以是1/2/3/4,因此有4个可能的数字。 但是,在矩阵中我想要' 1'发生70%(因此1号的总频率为140),' 2',' 3'和' 4',发生10%(因此2,3和4的频率为20)。

此外,我希望填充矩阵,以便2,3和4的值永远不会显示连续重复,但是1可能具有连续重复(因为它需要70%)

我有一个解决方案(没有连续的重复约束),使用repelem函数。但是,在目标PC上,安装了旧版本的matlab(2013)并且不包含此功能。 有人能为我提供解决方案吗?

由于

2 个答案:

答案 0 :(得分:0)

您可以使用以下方法

%represents odds map for 1,2,3,4
oddsMap = [0,0.7,0.8,0.9]; 

N = 200;
isValid = false;

while ~isValid
    %generate vector
    probVect = rand(N,1);
    randVect = ones(N,1);
    for ii=1:length(oddsMap)
        randVect(probVect>=oddsMap(ii)) = ii;
    end

    %check [2,3,4] constraint
    isValid = isempty(findstr(randVect',[2,3,4]));
end

答案 1 :(得分:0)

这是一种方法:

算法和代码

  • 创建一个60元素向量,值为2,3和4(随机排序),每次出现20次。

    a = repmat([2;3;4],20,1);    % Create vector of [2;3;4] 20 times
    a = a(randperm(numel(a)));   % Randomise intial vector
    
  • 获取连续值相等的所有位置的索引。

    d = find(diff(a)==0);  
    
  • 获取每个位置可以放置的最大数量,以便连续分解。

    maxones = floor(200/numel(d));
    
  • 在每个位置放置1到maxones个。这是为了尝试保持一定量的“随机性”,可以在每个位置放一个来分解它们!

    for ii = numel(d):-1:1; 
        a = [ a(1:d(ii)) ; ones(randi(maxones), 1) ; a(d(ii)+1:end) ]; 
    end
    
  • 现在随机添加剩余的数量,使向量为200个元素

    idx = randperm(numel(a), 200 - numel(a));
    for ii = numel(idx):-1:1; 
        a = [ a(1:idx(ii)); 1 ; a(idx(ii)+1:end) ]; 
    end
    

验证

输出是一个200个元素的向量,有20个元素,每个元素的值为2,3或4,140个元素的值为1.

% Using nnz (number of non-zero elements) to count matching condition 
nnz(a == 1) % = 140
nnz(a == 2) % = 20
nnz(a == 3) % = 20
nnz(a == 4) % = 20

没有连续的2s,3s或4s:

% Get number of elements where difference to next is 0, and value isn't 1
nnz([false; diff(a) == 0] & a ~= 1) % = 0