PERL: БИБЛИОТЕКА ПРОГРАММИСТА


PERL: БИБЛИОТЕКА ПРОГРАММИСТА - стр. 86


# weight_to_dist: получает хэш весовых коэффициентов

#  и возвращает хэш вероятностей
sub weight_to_dist {

my %weights = @>_; my %dist  =(); my $total  = 0; my ($key, Sweight); local $_;

foreach (values %weights) { $total += $_;

while (  ($key,   Sweight) = each %weights )  { $dist{$key} = $weight/$total;


80   Глава 2 • Числа

return %dist;

# weighted_ran: получает хэш вероятностей 8 и возвращает случайный элемент хэша sub weighted_rand {

my %dist = @_;

my ($key, $weight);

while (1)  {                   # Чтобы избежать погрешностей вычислений

# с плавающей запятой (см.  ниже), ray $rand = rand,

while (  ($кеу,   $weight) = each %dist )  { return $key if ($rand -= $weight) <0;

Комментарий

Функция gaussian_rand реализует полярный метод Бокса—Мюллера для преоб­разования двух независимых случайных чисел с однородным распределением, лежащих в интервале от 0 до 1 в два числа с математическим ожиданием 0 и стан­дартным отклонением 1 (то есть распределенных по закону Гаусса). Чтобы сгене­рировать числа с другим математическим ожиданием и стандартным отклонени­ем, умножьте выходные данные gaussian_rand на нужное стандартное отклонение и прибавьте математическое ожидание:

# gaussian_rand - см. выше

$mean = 25;

$sdev = 2;

Ssalary - gaussian_rand() * $sdev + $mean;

printf("You have been hired at \$%.2f\n",   Ssalary);

Функция weighted_rand получает случайное число из интервала от 0 до 1. За­тем она использует вероятности, сгенерированные weight_to_dist, и определяет, какому элементу соответствует это случайное число. Из-за погрешностей пред­ставления с плавающей запятой накопленные ошибки могут привести к тому, что возвращаемый элемент не будет найден. Поэтому код размещается в цикле while, который в случае неудачи выбирает новое случайное число и делает очередную попытку.

Кроме того, модуль Math::Random с CPAN содержит функции, генерирующие случайные числа для многих распределений.

t> Смотри также--------------------------------------------------------------------------------------------




Начало  Назад  Вперед