Если у вас нет веских причин, вы не хотите изобретать псевдослучайное поколение. Вполне возможно, что-то не так. Я бы предложил начать с массива с A [i] = i
затем сделайте это:
for (i=0; i< n; i++) {
j = random_number_between(i,n-1);
swap(A[i],A[j]);
}
Редактировать
Это в ответ на комментарии ниже:
Насколько случайным вы хотите, чтобы последовательность была. Обратите внимание, что неотъемлемой информацией в случайно выбранной перестановке является log (n!), Которая где-то близка к n / e битам. Таким образом, вам нужно генерировать столько случайных битов. Теперь, так как вы хотите, чтобы эти много случайных бит хранились где угодно, я думаю (больше похоже на интуицию, чем на математическое доказательство), было бы трудно сделать действительно случайную перестановку без такого большого количества памяти).
Но если вам просто нужна последовательность, которую нелегко реконструировать, вы можете просто объединить несколько функций 1: 1 одну за другой.
На ум приходят две вещи:
- сохранить счетчик i для последовательности, которая идет от 0 до N-1.
do log_2 (N / 2) бит переворачивается на i, где биты для перестановки выбираются случайным образом при запуске последовательности.
генерирует случайную перестановку по log_2 (N) битам в начале последовательности, используя вышеуказанный метод, а затем меняет местами биты в приведенном выше результате.
Найдите случайное число r1, которое является относительным простым числом к n at, и другое случайное число r2 между 0 и n-1. Ваш i-й номер = r2 ^ r% n.
Некоторая комбинация из них должна дать вам трудность для обратного проектирования последовательности. Ключевым моментом является то, что чем больше случайных битов вы добавляете, тем сложнее выполнить реинжиниринг.
Одна вещь, которая приходит на ум, это то, что если ваш диапазон равен 0..N-1, просто найдите большое число P, относительное простое число к N, и выберите другое случайное число