Сделать случайные числа наклонным / средним до определенного значения

Как я могу, например, сгенерировать список случайных чисел между 0 и 1, но иметь их значение 0,8?

Я написал этот маленький скрипт на C ++, который расскажет вам, какие числа получили выходные данные. Однако этот вопрос не связан с C ++.

#include  #include  #include  int main(int argCount, char** argVector) { std::cout << "Generating Randoms" << std::endl; float avarage = 0.F; srand(rand() + (int) time(NULL)); float ceiling = 0; float bottom = 1; for(unsigned int i = 0; i  ceiling) ceiling = random; else if(random < bottom) bottom = random; avarage += random; } std::cout << "Avarage: " << avarage/1000000 << std::endl; std::cout << "Ceiling: " << ceiling << std::endl; std::cout << "Bottom: " << bottom << std::endl; return 0; } 

Эти результаты:

 Generating Randoms Avarage: 0.499287 Ceiling: 1 Bottom: 0 

Я хотел бы, чтобы потолок и дно были все еще 0 и 1, но были в состоянии изменить среднее значение. Алгоритм также должен быть эффективным.

Еще раз, теперь я отправляю код на C ++, но любой язык будет делать.

У NolanPower была отличная идея с использованием полномочий, но механизм, который он рекомендовал для выбора мощности, отключен. Если случайные числа U равномерны (0,1), закон бессознательного статистика говорит, что мы можем получить ожидаемое значение любой функции g(U) как Integral[g(U) from: 0 to: 1] . Если наша функция g(U) является многочленом, т. U**c для некоторой константы c , то оценка интеграла дает общее решение 1 / (c + 1) как ожидаемое значение. Полагая это равным искомому среднему m и решению, получаем, что c = (1 / m) - 1 .

Чтобы получить ожидаемое значение 0,8, c = (1 / 0.8) - 1 = 0.25 , то есть выкрутить U**0.25 . Чтобы получить ожидаемое значение 0,2, c = (1 / 0.2) - 1 = 4 , т. Е. Сгенерировать значения с использованием U**4 .

Поднимите свой номер на .321928, мощность будет составлять в среднем 0,8 и все еще будет колебаться от 0 до 1.

Вот пример, который генерирует стандартное нормальное распределение, т. mu = 0, sigma = 1.

Я использовал трансформацию Box-Muller .

Все графики имеют x axis = value и y axis = frequency .

 #include  #include  #include  #include  int main(int argCount, char** argVector) { const double pi = 3.14159265359; const double nums = 1000000; double u, v, x; srand(rand() + (int) time(NULL)); for(unsigned int i = 0; i < nums; i++){ u = rand() / (((double)RAND_MAX) + 1.0); v = rand() / (((double)RAND_MAX) + 1.0); x = sqrt(-2*log(u)) * cos(2*pi*v); if (std::isfinite(x)){ std::cout << x <<" "; } } return 0; } 

standardnorm

 >>> np.std(nums) 1.0004139708929858 >>> np.average(nums) 7.1785002756408726e-05 

Вы можете смещать / масштабировать x мере необходимости, чтобы получить mu и sigma по вашему выбору.

Вот пример, который дает равномерное распределение с заданным mu :

 #include  #include  #include  #include  int main(int argCount, char** argVector) { const double pi = 3.14159265359; const double nums = 1000000; double x,mu; srand(rand() + (int) time(NULL)); mu = 3.0; for(unsigned int i = 0; i < nums; i++){ x = rand() / (((double)RAND_MAX) + 1.0); x *= 2*mu; if (std::isfinite(x)){ std::cout << x <<" "; } } return 0; } 

UNIF

 >>> np.average(nums) 3.0003091558133184 

Вы можете использовать документированный rand() % range + min для усечения.