Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Генерация случайной перестановки, Какие есть эффективные алгоритмы? 
:(
    Опции темы
CrazyHatter
Дата 17.10.2007, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 22.11.2004
Где: Москва

Репутация: нет
Всего: нет



Здравствуйте всем. У меня возник такой вопрос, может быть кто-нибудь подскажет:

Мне нужно сгенерировать случайную перестановку массива из N чисел [0, 1 ... N-1].

Очевидным способом будет генерация случайного числа в диапазоне [0, N-1] и занесение его на следующее место в ответе, а если это число уже присутствует в перестановке, то генерировать случайное число дальше до тех пор пока не получится ранее не встречавшееся. Т.е. пусть  X  - наша перестановка, тогда последовательно присваиваем X[0]=random(0, N-1), X[1]=random(0, N-1) и так далее. 

Однако такой способ очень накладный, когда приходится иметь дело с перестановкой из, скажем, 1000 элементов. На последней итерации придется полчаса ждать, пока сгенерируется одно единственное недостающее число.

Может быть кто-нибудь знает или встречал более эффективные алгоритмы получения случайной перестановки? Мне бы это очень пригодилось.
Спасибо.
PM MAIL   Вверх
Akina
Дата 17.10.2007, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



Цитата(CrazyHatter @  17.10.2007,  17:20 Найти цитируемый пост)
Очевидным способом будет 

Но неправильным. Правильно - генерировать случайное число в диапазоне от 1 до (макс. кол-во допустимых перестановок), и воспроизводить соответствующую перестановку.
Однако при большом количестве элементов генерация случайного числа может представлять значительные трудности...


Цитата(CrazyHatter @  17.10.2007,  17:20 Найти цитируемый пост)
генерация случайного числа в диапазоне [0, N-1] и занесение его на следующее место в ответе, а если это число уже присутствует в перестановке

вообще-то проще на втором шаге генерить в диапазоне [0, N-2], далее в диапазоне [0, N-3]... и считать соотв. элементы с учетом пропуска уже выбранных ранее.

Код

for i = 0 to n-1
  r = rand(i, n-1)
  swap x(r), x(i)
next



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
esperant0
Дата 17.10.2007, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 714
Регистрация: 20.5.2005

Репутация: 4
Всего: 14



Цитата(CrazyHatter @ 17.10.2007,  16:20)
 

Однако такой способ очень накладный, когда приходится иметь дело с перестановкой из, скажем, 1000 элементов. На последней итерации придется полчаса ждать, пока сгенерируется одно единственное недостающее число.

 

ДА есть способы.


Но Ваш имеет сложность n lg n . Почему Вы называете это очень накладным?

Добавлено через 5 минут и 17 секунд
Цитата(Akina @ 17.10.2007,  16:55)
Цитата(CrazyHatter @  17.10.2007,  17:20 Найти цитируемый пост)
Очевидным способом будет 

Но неправильным.  

Конечно правильным.


--------------------
 
 Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer 

Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором  а затем стерто и которое он - пользователь не мог видеть. 
PM MAIL   Вверх
JackYF
Дата 17.10.2007, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: нет
Всего: 162



рекомендую посмотреть в исходники stl на метод std::random_shuffle


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
esperant0
Дата 17.10.2007, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 714
Регистрация: 20.5.2005

Репутация: 4
Всего: 14



Цитата(JackYF @ 17.10.2007,  18:33)
рекомендую посмотреть в исходники stl на метод std::random_shuffle

зачем исходники? если просят алгоритм?


--------------------
 
 Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer 

Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором  а затем стерто и которое он - пользователь не мог видеть. 
PM MAIL   Вверх
JackYF
Дата 17.10.2007, 22:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: нет
Всего: 162



Цитата(esperant0 @  17.10.2007,  21:38 Найти цитируемый пост)
зачем исходники?

из исходников при удачных условиях можно понять алгоритм.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
sergejzr
Дата 17.10.2007, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 4
Всего: 360



Цитата(JackYF @  17.10.2007,  17:33 Найти цитируемый пост)
рекомендую посмотреть в исходники stl на метод std::random_shuffle


Там как раз алг, который Akina в три строки написал smile


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
CrazyHatter
Дата 18.10.2007, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 22.11.2004
Где: Москва

Репутация: нет
Всего: нет



2 Akina: Спасибо, вот это наверное как раз то, что я искал:

Код

for i = 0 to n-1
  r = rand(i, n-1)
  swap x(r), x(i)
next


Цитата

Но Ваш имеет сложность n lg n . Почему Вы называете это очень накладным?


2 esperant0: просто я пишу метод, который требует последовательного построения достаточно большого числа случайных перестановок. В моем массиве порядка 2000 значений, а если перестановок будет, скажем, несколько десятков тысяч, то использование неэффективного алгоритма заметно увеличит время работы.

Цитата

рекомендую посмотреть в исходники stl на метод std::random_shuffle


2 JackYF: кстати, спасибо, я не знал что такой есть. вполне возможно, что пригодится. smile 




PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0497 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.