Пример распределения по Парето

22

Распределение Парето - это распределение вероятностей, которое встречается в природе. У этого есть много специальных свойств, таких как бесконечное среднее. В этом задании вы выведете число, выбранное из этого распределения.

Распределение Парето определяется как большее или равное xс вероятностью 1/x, для всех xбольшее или равное 1.

Следовательно, число, выбранное из этого распределения, больше или равно 1 с вероятностью 1, больше или равно 2 с вероятностью точно 1/2, больше или равно 3 с вероятностью точно 1/3, больше или равно 11,4 с вероятностью ровно 1 / 11,4 и так далее.

Так как вы выполните выборку этого распределения, ваша программа или функция не будет вводить и выводить случайное число с указанными выше вероятностями. Однако, если ваша программа не полностью соответствует вышеуказанным вероятностям из-за впечатлений с плавающей точкой, это нормально. Смотрите в нижней части задачи для более подробной информации.

(Точнее, это называется распределение Парето с альфа 1 и нижней границей 1)

Вот 10 примеров из этого распределения:

1.1540029602790338
52.86156818209856
3.003306506971116
1.4875532217142287
1.3604286212876546
57.5263129600285
1.3139866916055676
20.25125817471419
2.8105749663695208
1.1528212409680156

Обратите внимание, что 5 из них ниже 2, а 5 выше 2. Поскольку это средний результат, он, конечно, мог бы быть выше или ниже.

Ваш ответ должен быть верным только в пределах вашего типа с плавающей запятой, типа действительного числа или чего-либо еще, что вы используете, но вы должны иметь возможность представлять числа с точностью не менее 3 десятичных цифр и представлять числа до 1 000 000 , Если вы не уверены, что что-то в порядке, не стесняйтесь спрашивать.

Это код гольф.


Подробности о неточности:

  • Для каждого диапазона [a, b], где 1 <= a < bидеальная вероятность того, что выборка попадет в этот диапазон, равна 1/a - 1/b. Вероятность того, что ваша программа производит ряд в этом диапазоне должна быть с 0.001о 1/a - 1/b. Если Xвывод вашей программы, это требуется |P(a <= X <= b) - (1/a - 1/b)| < 0.001.

  • Следует отметить , что путем применения вышеуказанного правила с a=1и bдостаточно большим, это тот случай, когда программа должна выводить число , большее или равное 1, по меньшей мере вероятностью 0,999. В остальное время может произойти сбой, вывод Infinityили что-то еще.

Я вполне уверен, что существующие представления в форме 1/1-xили 1/x, где xслучайное плавание в [0, 1)или (0, 1)или [0, 1], все удовлетворяют этому требованию.

isaacg
источник
2
Примечание для всех: issacg добавил некоторые правила, которые допускают некоторые неточности, поэтому большинство ответов здесь длиннее, чем необходимо. [извините за злоупотребление комментариями тоже, но это то, что произойдет, когда ОП значительно изменит вопрос]
user202729

Ответы:

6

MATL , 3 байта

1r/

Попробуйте онлайн! Или оцените получающиеся вероятности , выполняя это 10000 раз.

объяснение

1    % Push 1
r    % Push random number uniformly distributed on the open interval (0,1)
/    % Divide. Implicitly display
Луис Мендо
источник
После уточнения и редактирования в ОП этот ответ соответствует правилам испытания
Луис Мендо
5

R, 10 байт

1/runif(1)

Довольно просто.

plannapus
источник
2
Обратите внимание, что runif никогда не возвращает 0 или 1 в случае по умолчанию, поэтому проблем с этим нет.
Джузеппе
Да, спасибо. И я не думал об этом при вводе этого ответа, но вы действительно можете проверить распределение при необходимости.
plannapus
2
@ Это неправильно. Распределение Парето абсолютно непрерывно и поэтому имеет меру 0 для любого числа.
Therkel
3
@Mego Хорошо, это может быть зыбучие пески для меня (учитывая, что я почти ничего не знаю о плавающей запятой), но я на самом деле думаю, что, хотя вероятность runifдать 1 равна нулю, вероятность 1/runifдать 1 не равна, из-за точности с плавающей запятой ( т.е. обычно 1 / 0.9999999 возвращает 1 в R).
plannapus
1
@plannapus Хмм ... Это хорошая мысль. Поплавки делают это слишком сложным.
Мего
4

TI-Basic, 2 байта

rand^-1      (AB 0C in hex)

Для всех, кто интересуется, randвозвращает случайное значение в (0,1]. "Из-за особенностей алгоритма генерации случайного числа наименьшее число, которое можно сгенерировать, немного больше 0. Наибольшее возможное число на самом деле 1 ... "( источник ). Например, высевающий ранд с 196164532 дает 1.

Timtech
источник
Как ни странно, эквивалентный код не будет работать на калькуляторе серии TI-89. Несмотря на то, что их генераторы случайных чисел практически идентичны, TI-89 будет возвращать 0 всякий раз, когда TI-83 + будет возвращать 0,999999999999889.
Миша Лавров
2
Разработчики TI-Basic заранее знали, что этот вызов случится ...? Кажется, на этот раз победить.
user202729
@ user202729 Избегание 0 и 1 делает его randболее полезным в качестве подпрограммы для других команд калькулятора, и, вероятно, именно поэтому TI приняла это дизайнерское решение. Например, randNorm(0,1возвращается -7.02129...с начальным значением 196164532. Использование алгоритма ГСЧ без корректировки дало бы значение 1e99, которое является необоснованным значением для нормально распределенной переменной.
Миша Лавров
@ user202729 Да, на самом деле я потратил немного времени, чтобы все это сделать. Определенно стоит того для этих голосов.
Timtech
4

R , 12 байт

exp(rexp(1))

Попробуйте онлайн!

Проверьте распределение

Это использует другой подход, используя тот факт, что если Y~exp(alpha), то X=x_m*e^Yэто Парето с параметрами x_m,alpha. Поскольку оба параметра равны 1, а параметр скорости по умолчанию для rexp1 равен 1, это приводит к соответствующему распределению Парето.

Хотя этот ответ является довольно специфичным для R подходом, он, к сожалению, менее гольфы, чем plannapus » .

R , 14 байтов

1/rbeta(1,1,1)

Попробуйте онлайн!

Еще меньше гольфа, но другой способ получить ответ.

Другое свойство экспоненциального распределения состоит в том X ~ Exp(λ) then e^−X ~ Beta(λ, 1), что если , следовательно, 1/Beta(1,1)является Pareto(1,1).

Кроме того, увлеченный наблюдатель может вспомнить, что если X ~ Beta(a,b)и a=b=1тогда X~Unif(0,1), то это действительно так 1/runif(1).

Giuseppe
источник
Не имею представления. Но реальность такова, что существует огромная путаница в том, что разрешено, а что нет в этом вызове.
user202729
@ user202729 это справедливо, но те, кто высказывал опасения по этому поводу, по крайней мере, прокомментировали бы, так что отрицательное голосование (на мой взгляд) вряд ли будет связано с этим. РЕДАКТИРОВАТЬ: таинственный downvoter удалил downvote.
Джузеппе
Я понизил голосование, потому что я думал, что использование R на вызове, как это было тривиально, но я был немного счастлив. Я понимаю, что для этого используется метод, отличный от большинства других ответов, поэтому я убрал свое отрицательное мнение.
KSmarts
@KSmarts «Тривиальный» ответ в R фактически никем не использовался: actuar::rpareto(1,1,1)потому что он длиннее :)
plannapus
Для информации есть ок. 20 дистрибутивов жестко запрограммированы в базе R, но Pareto не является одним из них, поэтому необходимо использовать обходной или дополнительный пакет.
plannapus
3

Древесный уголь , 10 байт

I∕Xφ²⊕‽Xφ²

Попробуйте онлайн!

Ссылка на подробную версию:

Print(Cast(Divide(Power(f, 2), ++(Random(Power(f, 2))))));

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

  • У древесного угля есть только методы для получения случайных целых чисел, поэтому, чтобы получить случайное число с плавающей запятой от 0 до 1, мы должны получить случайное целое число от 0 до N и разделить на N.
  • Предыдущая версия этого ответа, в которой использовалась 1/(1-R)формула: в этом случае N устанавливается равным 1000000, так как ОП запрашивает минимальное значение. Чтобы получить это число, Charcoal предоставляет заданную переменную f= 1000. Так что вычисления f^2мы получаем 1000000. В случае, если случайное число 999999 (максимум), 1/(1-0.999999)=1000000.
  • Совет Нейла (сохранение 3 байта): Если у меня есть 1/(1-R/N)где Rслучайное число между 0 и N, это то же самое, что просто вычислить N/(N-R). Но учитывая, что случайные целые числа N-Rи Rимеют одинаковую вероятность появления, это то же самое, что и просто вычисление N/R( Rв этом последнем случае число от 1 до N включительно, чтобы избежать деления на ноль).
Чарли
источник
10 байт
Нил
@ Нил, пожалуйста, подожди минутку, пока я попытаюсь понять, что делает твой код ... :-)
Чарли
На самом деле мне больше не нужно MapAssignRight, 10 байтов! работает.
Нил
@Neil ассимиляция вашего кода завершена! Ответ отредактирован. :-D
Чарли
3

Haskell , 61 56 байт

Функция randomIO :: IO Floatгенерирует случайные числа в интервале [0,1) , поэтому преобразование их с использованием x -> 1/(1-x)приведет к реализации Парето.

import System.Random
randomIO>>=print.(1/).((1::Float)-)

Попробуйте онлайн!

flawr
источник
Перемещение аннотации типа экономит несколько байтов:randomIO>>=print.((1::Float)/)
Laikoni
И поскольку функции разрешены, я бы сказал, что вы можете отбросить main=.
Лайкони
Приблизительно диапазон [0,1)соответствует этому ответу
flawr
@flawr Ой, ты прав! Я забыл, как поплавки работают временно.
Мего
Ну, в любом случае, спасибо за комментирование, я бы даже не догадывался :)
flawr
3

Excel, 9 байт

=1/rand()

Да, Excel (полу) конкурентоспособен за изменения!

Therkel
источник
Также работает в LibreOffice Calc :)
ElPedro
Вы можете изменить это на Google листы для -1 байт ( =1/Rand()
Тейлор Скотт
3

Mathematica, 10 байт

1/Random[]

Попробуйте онлайн!

-4 байта от М.Штерна

J42161217
источник
2
Это может привести к сбою, потому что RandomRealвыводит действительное число в закрытом диапазоне [0, 1]. Таким образом, деление на 0 возможно. Вам нужно будет манипулировать случайным значением, чтобы удалить эту возможность.
Мего
2
@ Мего, где именно ты нашел эту информацию?
J42161217
1
@Mego, какова вероятность получить 0?
J42161217
4
Jenny_mathy: Согласно предложению о мета, the burden of proof should be on the person claiming to have a valid answerвы должны доказать, что оно действительно, а не просить @Mego предоставить неверный контрольный пример. Кроме того, поскольку float дискретен, вероятность получить 0 не равна нулю.
user202729
1
Возвращаясь к теме, я не верю, что есть возможность получить ноль с помощью этой функции. Mathematica на самом деле будет производить цифры меньше, чем $MinMachineNumber. Попробуйте это: Table[RandomReal[{0, $MinMachineNumber}], 100]. Оказывается, Mathematica достаточно умен, чтобы отказаться от номеров машин и перейти к числам произвольной точности. СМЕШНО.
Келли Лоудер
2

Рубин, 14 8 байт

p 1/rand

Тривиальная программа, я не думаю, что она может стать короче.

гигабайт
источник
Примечание для всех: issacg добавил некоторые правила, которые допускают некоторые неточности, поэтому большинство ответов здесь длиннее, чем необходимо.
user202729
2

Excel VBA, 6 байт

Функция анонимного непосредственного окна VBE, которая не требует ввода и вывода в непосредственное окно VBE

?1/Rnd
Тейлор Скотт
источник
1

Python , 41 байт

lambda:1/(1-random())
from random import*

Попробуйте онлайн!


Использование встроенного на самом деле дольше:

Python , 43 байта

lambda:paretovariate(1)
from random import*

Попробуйте онлайн!

Оба решения работают как в Python 2, так и в Python 3.

Mego
источник
1
Полные программы короче для задач, которые не используют ввод, используя printсохраняет байт.
Эрик Outgolfer
1

J , 5 байт

%-.?0

Как это работает:

?0 генерирует случайное значение больше 0 и меньше 1

-. вычесть из 1

% обоюдный

Попробуйте онлайн!

Гален Иванов
источник
Примечание для всех: issacg добавил некоторые правила, которые допускают некоторые неточности, поэтому большинство ответов здесь длиннее, чем необходимо.
user202729
1

Красный , 19 байт

1 /(1 - random 1.0)

Попробуйте онлайн!

Гален Иванов
источник
Примечание для всех: issacg добавил некоторые правила, которые допускают некоторые неточности, поэтому большинство ответов здесь длиннее, чем необходимо.
user202729
1

APL (Dyalog) , 5 байтов

÷1-?0

Попробуйте онлайн!

Как?

 ÷   1-     ?0
1÷  (1-  random 0..1)
Уриэль
источник
Примечание для всех: issacg добавил некоторые правила, которые допускают некоторые неточности, поэтому большинство ответов здесь длиннее, чем необходимо.
user202729
1

Japt , 6 байт

1/1-Mr такой же длины, но это было немного менее скучно!

°T/aMr

Попытайся


объяснение

Увеличиваем ( °) ноль ( T) и делим на ( /) его абсолютную разницу ( a) с Math.random().

мохнатый
источник
Примечание для всех: issacg добавил некоторые правила, которые допускают некоторые неточности, поэтому большинство ответов здесь длиннее, чем необходимо.
user202729
1

Желе , 5 байт

Желе также не имеет случайного числа с плавающей точкой, так что это использует x/n , где xэто случайное число в диапазоне [1, n](включительно) для имитации случайного поплавка в диапазоне (0, 1]. В этой программе nустановлено быть .108

ȷ8µ÷X

Попробуйте онлайн!

объяснение

ȷ8     Literal 10^8.
  µ    New monad.
   ÷   Divide by
    X  random integer.

Подключить , 3 байта

ØXİ

Попробуйте онлайн!

Подключить бьет желе! (TI-Basic еще нет)

объяснение

  İ    The inverse of...
ØX     a random float in [0, 1)

Конечно, это имеет ненулевую вероятность принять обратное значение 0.

user202729
источник
Не ØXвернется 0ли решение Enlist, если вернется ? (Отказ от ответственности: я не знаю, Записаться на всех!)
Shaggy
@Shaggy your program must output a number greater than or equal to 1 with at least probability 0.999. The rest of the time it may crash(из правил
конкурса
1

IBM / Lotus Notes Formula, 13 байтов

1/(1-@Random)

Образец (10 прогонов)

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

ElPedro
источник
Примечание для всех: issacg добавил некоторые правила, которые допускают некоторые неточности, поэтому большинство ответов здесь длиннее, чем необходимо.
user202729
Не уверен, что я смогу сделать это намного короче, какие бы изменения правил не были сделаны :)
ElPedro
1

JavaScript REPL, 15 19 байт

1/Math.random()
l4m2
источник
3
Это не даст правильных результатов, если Math.random() вернет 0
Mr. Xcoder
1
Наверное 1/(1-Math.random())?
user202729
Исправлено с использованием решения u * 29
l4m2
Вам нужно _=>с самого начала сделать это функцией; фрагменты не допускаются.
Лохматый
Это полная программа с использованием консоли
l4m2
0

J, 9 байт

p=:%@?@0:

Я не мог понять, как сделать так, чтобы это не занимало ввода, так как p =:%? 0 оценивал бы сразу и оставался фиксированным. Из-за этого это своего рода долго.

Как это работает:

p=:        | Define the verb p
       0:  | Constant function. Returns 0 regardless of input.
     ?@    | When applied to 0, returns a random float in the range (0,1)
   %@      | Reciprocal

Оценивается 20 раз:

    p"0 i.20
1.27056 1.86233 1.05387 16.8991 5.77882 3.42535 12.8681 17.4852 2.09133 1.82233 2.28139 1.58133 1.79701 1.09794 1.18695 1.07028 3.38721 2.88339 2.06632 2.0793
Bolce Bussiere
источник
0

Pyth , 4 байта

c1O0

Попробуй это здесь!

Альтернатива: c1h_O0.

Мистер Xcoder
источник
c1tOZ5, не работает?
Дейв
@Dave Не работает, возвращает отрицательные значения. Мне 1-nне нужноn-1
г-н Xcoder
У Пифа нет константы для 100?
Лохматый
@ Шэгги, я бы хотел, чтобы это случилось. К сожалению, не константа для 100AFAIK
г-н Xcoder
0

Чисто , 91 байт

import StdEnv,Math.Random,System.Time
Start w=1.0/(1.0-hd(genRandReal(toInt(fst(time w)))))

Чистый не любит случайных чисел.

Поскольку генератору случайных чисел (Mersenne Twister) нужно дать начальное число, мне нужно взять системную временную метку, чтобы получить что-то, что отличается пассивно для каждого прогона, и для выполнения всего, что связано с IO, мне нужно использовать целое Startобъявление, потому что это Единственное место для получения World.

Попробуйте онлайн!

Οurous
источник