2013-05-20 2 views
0

Если я хочу сгенерировать 1000 чисел от 0 до 999, которые являются уникальными, что мне делать?
Моя первая попытка - создать массив {0, 1, 2, ..., 999} и использовать std::random_shuffle, чтобы перетасовать их. Однако, поскольку я должен генерировать числа в длинном цикле, скажем, O (10^7), этот подход будет подавлять время работы.
Есть ли лучший способ решить эту проблему?Произвольно генерировать n уникальных чисел

+2

Почему это должно быть 10^7 для генерации 100 номеров – aaronman

+0

@aaronman Это не то, что сказал ОП. Ему нужно сгенерировать их в цикле, который будет работать около 10^7 раз. – Elazar

+2

с различным набором случайных чисел каждый раз? В чем цель этого, я не думаю, что мы сможем решить проблему без дополнительной информации, и вы не будете генерировать другой набор случайных чисел каждый раз, не пройдя все 1000 чисел. – aaronman

ответ

5

Если вы сохраните массив 1000 номеров, сохраненных и вызвать std::random_shuffle каждый раз, когда вам нужно в цикле, что на самом деле самый быстрый способ, которым вы сможете генерировать 1000 случайных уникальных номеров так, как вам нужно. Вам не нужно повторно создавать массив каждый раз.

Не имеет значения, имеет ли ваша петля O (10^7) итерации, потому что если вы собираетесь использовать эти 1000 целых чисел, как вы говорите, вам нужно, пройдите через каждое из этих чисел, как вы их используете. std::random_shuffle сложность времени также O (n), поэтому она не собирается замедлять вас гораздо больше.

+0

Это. Генерация 1000 чисел - это O (n), а random_shuffle - O (n), так что по определению вы не можете пойти ни на что ниже. – Patashu

+0

Асимптотически, да. но просто чтение значений может быть быстрее, чем генерировать их. – Elazar

+0

Спасибо, это ускорит код. –

1

Вы запрашиваете реализацию shuffle (это точное описание вашего требования), которое будет лучше, чем в стандартной библиотеке. Это длинный выстрел.

Но я попробую. Я бы сказал: подготовьте файл с 10^7 такими перестановками и прочитайте его. Обязательно предварительно сделайте предварительную выборку, иначе она будет медленнее. Если вы предварительно отбираете в другой поток, это может быть быстрее. Но это всего лишь дикая догадка.

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

1
  1. Сохраните номер контейнера в другой контейнер C2.

  2. Создать индекс элемента для выбора случайного элемента в C1. Каждый раз, когда вы создаете индекс, удалите его из контейнера C1. Итак, в следующий раз вы получите уникальный номер.

  3. После C1 становится пустым, заселить C1 с C2 и перейти к шагу 2.

Смежные вопросы