Создание упорядоченного массива случайных чисел

Алгоритмы: от сортировки пузырьком до численных методов

Модераторы: C_O_D_E, DeeJayC

AMDemon
Сообщения: 24
Зарегистрирован: 18 ноя 2005, 21:09
Откуда: Брянск

Задача звучит так: создать массив целых чисел длины n, элементы которого не отрицательны и не превышает k. n и k задаются пользователем.
Без последнего условия задача решается крайне просто:
randomize();
array[0]=random(10);
for (i=1;i<n;i++) array+=random(10);
Но когда k<n начинаются поблемы...
Есть у кого-нибудь идеи?
Крылья есть у всех -
У каждого свой путь наверх!
Albor
Сообщения: 491
Зарегистрирован: 06 сен 2004, 13:34
Откуда: Днепропетровск

Судя по задаче, нужно создать массив размерности n, а, затем, заполнить его значениями от 0 до k. При чём здесь k<n? Эти параметры вообще не пересекаются. В приведенном листинге инициализируется только 0-й элемент массива, а остальные?
Аватара пользователя
Oscar
Сообщения: 963
Зарегистрирован: 29 май 2004, 13:44
Откуда: Мюнхен (рожден в Киеве)
Контактная информация:

AMDemon писал(а):элементы которого не отрицательны и не превышает k.
Прошу прощения, что не превышаЕТ k ?
AMDemon
Сообщения: 24
Зарегистрирован: 18 ноя 2005, 21:09
Откуда: Брянск

Ошибку увидел.
array[0]=random(10); // инициализация первого
for (i=1;i<n;i++)
array=array[i-1]+random(10); // инициализация остальных, каждый заранее больше предыдущего
А у меня элементов больше миллиона. При таком алгоритме значение элемента на каком-то этапе превышает integer. Массивов у меня много и их упорядочивание длится дольше чем сутки, на большее терпения у меня не хватило.
Крылья есть у всех -
У каждого свой путь наверх!
Albor
Сообщения: 491
Зарегистрирован: 06 сен 2004, 13:34
Откуда: Днепропетровск

Может быть стоит сначала заполнить массив, а затем отсортировать его (не методом пузырька, конечно)? И без сложения с предыдущим элементом. Или задача стоит получить неповторяющиеся числа? Если случайное число получать способом остатка от деления на k, то число никогда не превысит предел. Например, если k=565, то случайное число получаем random()*1000%k (random() должна возвращать число от 0 до 1, хотя и не обязательно), результат будет лежать в интервале >=0 и < 565
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

А если так:

1. Delta=K/N
2. Для i={0..N-1}: X=i*Delta+Random(0..Delta)

Т.е. заполняем массив линейной функцей i*K/N, но каждому элементу задаем случайный сдвиг на +{0..шаг}.
DeeJayC
Сообщения: 497
Зарегистрирован: 17 фев 2004, 11:26
Откуда: Ленинград (который Город на Неве)
Контактная информация:

Naeel Maqsudov, Так делать нельзя - надо исследовать вопрос о распределении и случайности чисел X.
"Особое внимание начинающих аквариумистов хотим обратить на то, что рыбки никогда не спят на спинке!" (c)

viel spass, DeeJayC
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

В задаче про это ничего на сказано. Если считать что функция Random дает числа, появление каждого из которых равновероятно, то предлагаемое решение является как нельзя лучшим.

Этот алгоритм можно улучшить.
Если "окно", задаваемое случайным смещением расширить. Сделать, скажем не +{0..шаг}, а +{0..шаг*2}. То в присвоение X надо будет поставить в еще один вложенный цикл, прерываемый по условию X>=X[i-1]. (Разумеется крайние элементы массива будут являться особыми случаями.)

Можно предположить, что в среднем внутренний цикл будет выполняться 2 раза, так как половина "окна" пересевается с другим окном. Однако, это все равно несравнимо лучше, чем алгоритм с сортировкой на втором проходе.
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

О! Можно БЕЗ вложенного цикла обойтись!

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


Даже можно еще короче сформулировать:

Тут надо рассчитывать только значение верхней границы окна - это линейная функция от i. Нижняя граница окна равна предыдущему значению X, а для первого шага берется равной 0.
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

Вот наиболее общая формулировка моего решения:

Дано:
Kmin,Kmax-предельные значения величины X,
N-количество элементов,
P-ширина окна (0<=P<Kmax). Чем больше P тем "разболтаннее" получится картина. При P=0 результат получится аналогичный предложенному мною в первый раз.

X[-1]=0 //Это начальное условие, а не элемент массива.
i=0..N-1:
X=X[i-1]+random((Kmax-P)*(i+1)/N-X[i-1])+Kmin
Ответить