Использование randi в MATLAB для получения случайных значений: значения распределены неравномерно

#matlab #random

#matlab #Случайный

Вопрос:

Я генерирую случайную совокупность строк, состоящих из 0 и 1. Я использую randi(2)-1 для получения случайно сгенерированного единичного значения 0 или 1. Я ожидаю получать 1 почти так же часто, как 0. Вместо этого, когда я просматриваю всех особей в популяции, они в основном состоят из единиц. Ниже приведен код — что не так?

 for iInd=1:individualsCount
    individual(attrCount) = 0;

    for i=1:attrCount
         individual(i) = randi(2)-1;
    end

    population{iInd} = individual;
end
  

Ответ №1:

Во-первых, вам не нужен цикл для генерации случайной строки из 0 и 1. Попробуйте это вместо этого:

 individual = randi([0 1],[attrCount,1]);
  

Во-вторых, опять же, вам не нужен цикл для построения вашей population ячейки. Попробуйте это вместо:

 population=arrayfun(@(x)randi([0 1],[attrCount,1]),1:individualsCount,'UniformOutput',false)
  

Возможно, вам придется изменить порядок строк и столбцов в зависимости от того, как вы хотите его настроить.


Теперь, переходя к вашему вопросу, вы должны понимать, что эти распределения являются стохастическими и приближаются к действительно равномерному распределению 50% 1 и 50% 0 только по мере приближения размера вашей выборки к бесконечности. Если ваш attrCount достаточно мал, не удивляйтесь, если вы не найдете цифр, близких к 50% для каждого. Это не значит, что это неправильно. Это то, что есть.

Вот как выглядит распределение единиц для случайного двоичного вектора разных размеров выборки. Вы можете видеть, что при небольших размерах выборки наблюдается высокая вариабельность (и это ни в коем случае не точно… каждый раз это будет по-разному), тогда как по мере того, как вы начинаете приближаться к большим размерам выборки от 1000 и выше, ваше распределение единиц становится все ближе и ближе к 50%, в конечном итоге составляя ровно 50% на бесконечности.

введите описание изображения здесь

Комментарии:

1. В качестве отступления: обратите внимание, что из-за компилятора JIT в последних выпусках Matlab циклы for уже не так плохи, как раньше. В зависимости от значений attrCount и individualsCount , явный цикл for может быть в 4 раза быстрее, чем arrayfun . Очевидно, однако, что запрос двумерной матрицы (attrCount x individualsCount) из randi является наиболее эффективным решением.

2. @MattB. Я согласен, компилятор JIT добился немалых успехов. Я снова использовал MATLAB несколько месяцев назад после короткого перерыва, и я был шокирован тем, как неуклюжее вложенное решение 4 для цикла моего друга было в 2 раза быстрее, чем мое «умное», компактное и векторизованное решение (которое раньше было намного быстрее циклов в прошлом).