Генерация отсортировала случайный ints без вида? O (n)

В моем случае мы создаем продукт, для которого у нас есть решение для Visual Studio с различными компонентами в их собственных проектах. Общие атрибуты идут. В решении существует приблизительно 35 проектов и общая информация о блоке (CommonAssemblyInfo.cs), который имеет следующие атрибуты:

[assembly: AssemblyCompany("Company")]
[assembly: AssemblyProduct("Product Name")]
[assembly: AssemblyCopyright("Copyright © 2007 Company")]
[assembly: AssemblyTrademark("Company")]

//This shows up as Product Version in Windows Explorer
//We make this the same for all files in a particular product version. And increment it globally for all projects.
//We then use this as the Product Version in installers as well (for example built using Wix).
[assembly: AssemblyInformationalVersion("0.9.2.0")]

другие атрибуты, такие как AssemblyTitle, AssemblyVersion и т.д., мы предоставляем на основе на блок. При создании блока и AssemblyInfo.cs и CommonAssemblyInfo.cs встроены в каждый блок. Это дает нам лучший из обоих миров, где можно хотеть иметь некоторые общие атрибуты для всех проектов и определенные значения для некоторых других.

Hope, которая помогает.

17
задан Community 23 May 2017 в 12:26
поделиться

8 ответов

Итак, вы спрашиваете, будут ли сгенерированные таким образом числа быть равномерно распределенными.

Вы генерируете ряд:

y j = ∑ i = 0 j (x i / A)

, где A - сумма всех x i . x i - список (положительных) дельт.

Это можно сделать, если и только если x i распределены экспоненциально (с любым фиксированным средним). Итак, если x i равномерно распределены, результирующий y j не будет равномерно распределен.

Сказав это, довольно легко сгенерировать экспоненциальную x i значений.

Одним из примеров может быть:

sum := 0
for I = 1 to N do:
    X[I] = sum = sum - ln(RAND)
sum = sum - ln(RAND)
for I = 1 to N do:
    X[I] = X[I]/sum

, и ваши случайные числа будут отсортированы в диапазоне [0, 1) .

Ссылка: Создание отсортированных списков случайных чисел . В документе есть и другие (более быстрые) алгоритмы.

Конечно, это генерирует числа с плавающей запятой. Для равномерного распределения целых чисел вы можете заменить sum выше на sum / RANGE на последнем шаге (т. Е. RHS становится X [I] * RANGE / sum , а затем округлить числа до ближайшего целого).

18
ответ дан 30 November 2019 в 12:13
поделиться

Равномерное распределение имеет верхнюю и нижнюю границы. Если вы используете предложенный вами метод и ваши дельты выбраны достаточно большими, чтобы вы натолкнулись на верхнюю границу, прежде чем сгенерировали все свои числа, что будет делать ваш алгоритм дальше? распределение Пуассона , которое представляет собой распределение интервалов времени между случайными событиями, происходящими с заданной средней частотой.

5
ответ дан 30 November 2019 в 12:13
поделиться

Если вы возьмете диапазон чисел от 1 до 1000, и вам нужно будет использовать 100 из этих чисел, дельта должна быть как минимум 10, иначе вы не сможете достичь 1000 отметка. Как насчет того, чтобы поработать, чтобы продемонстрировать это в действии ...

Вероятность любого заданного числа в равномерно распределенной случайной выборке составляет 100/1000, например, 1/10 - никакого шока, возьмите это за основу.

Предполагая, вы начинаете использовать дельту, и эта дельта равна всего 10.

Шансы получить число 1 составляют 1/10 - кажется, нормально. Шансы на получение числа 2 составляют 1/10 + (1/10 * 1/10) (потому что вы можете получить 2 дельты из 1 подряд или просто получить 2 в качестве первой дельты). Шансы на получение числа 3 равны 1/10 + (1/10 * 1/10 * 1/10) + (1/10 * 1/10) + (1/10 * 1/10)

Первый случай - дельта 3, второй - 3 дельты из 1 подряд, третий случай - дельта 1, за которой следует 2, а четвертый случай - дельта 2, за которой следует 1.

Ради того, чтобы я мог печатать пальцами, мы не будем генерировать комбинации, которые достигают 5.

Сразу же первые несколько чисел имеют больший процентный шанс, чем прямые случайные числа.

Это можно изменить, изменив значение дельты, чтобы все дроби были разными, но я не верю, что вы могли бы найти дельту, которая давала бы одинаковые шансы.

Приведу аналогию, которая могла бы просто понизить ее, если учесть ваша дельта равна 6, и вы запускаете ее дважды, это эквивалентно бросанию двух кубиков - каждая из дельт независима,

4
ответ дан 30 November 2019 в 12:13
поделиться

Я думаю, что это будет очень похоже, но крайности будут другими из-за нормализации. Например, 100 чисел, выбранных случайным образом от 1 до 100, могут быть 1. Однако все 100 чисел, созданных с использованием вашей системы, могут иметь дельты 0,01, но когда вы их нормализуете, вы увеличите их до диапазона 1 -> 100, что будет означать, что у вас никогда не будет такой странной возможности набора очень низких чисел.

2
ответ дан 30 November 2019 в 12:13
поделиться

Ответ Алока и комментарий Дэна Дайера указывают на то, что использование ] экспоненциальное распределение для дельт даст равномерное распределение целых чисел.

Итак, новая версия образца кода в вопросе будет:

import random,sys
running = 0
max = 1000
deltas = [random.expovariate(1.0) for i in range(0,11)]
floats = []
for d in deltas:
    running += d
    floats.append(running)
upper = floats.pop()
ints = [int(round(f/upper*max)) for f in floats]
print(ints)

Обратите внимание на использование random.expovariate (1.0) , Python-генератор случайных чисел с экспоненциальным распределением (очень полезно!). Здесь оно вызывается со средним значением 1,0, но поскольку сценарий нормализует последнее число в последовательности, само среднее значение не имеет значения.

Вывод (справедливый бросок кубиков):

[11, 43, 148, 212, 249, 458, 539, 725, 779, 871]
2
ответ дан 30 November 2019 в 12:13
поделиться

Q: Будет ли результирующее распределение целых чисел таким же, как генерация 100 случайных целых чисел из равномерно распределенной функции плотности вероятности?

A: Каждая дельта будет равномерно распределена. Центральная предельная теорема говорит нам, что распределение суммы большого числа таких отклонений (поскольку они имеют конечное среднее значение и дисперсию) будет стремиться к нормальному распределению. Следовательно, более поздние отклонения в вашей последовательности не будут распределены равномерно.

Таким образом, краткий ответ - «нет». Боюсь, что я не могу дать простое решение , не занимаясь алгеброй. У меня сегодня нет времени на это!

1
ответ дан 30 November 2019 в 12:13
поделиться

Вы можете сделать это за два прохода;

на первом проходе, сгенерировать дельты между 0 и (MAX_RAND / n)

на втором проходе, нормализовать случайные числа, чтобы они были в пределах

По-прежнему O (n), с хорошим местоположением ссылки.

0
ответ дан 30 November 2019 в 12:13
поделиться

Ссылка (1979) в ответ Алока интересна. Он дает алгоритм для генерации статистики равномерного порядка не сложением, а последовательным умножением:

max = 1.
for i = N downto 1 do
   out[i] = max = max * RAND^(1/i)

где RAND равномерно на [0,1). Таким образом, вам не нужно выполнять нормализацию в конце и даже не хранить числа в массиве; вы можете использовать это как итератор.

Экспоненциальное распределение: теория, методы и приложения Автор Н. Балакришнан, Асит П. Басу дает другой вывод этого алгоритма на стр. 22 и цитирует Мальмквиста (1950).

1
ответ дан 30 November 2019 в 12:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: