LINUX.ORG.RU

Перебрать все сочетания из N по 2


0

1

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

Это возможно?

Потому что если память выделять, я их современно перетасую и вытащу.



Последнее исправление: Indaril_Shpritz (всего исправлений: 1)

Без выделения памяти минимум на N(N-1)/2 бит не придумывается.

Elyas ★★★★★
()

Твоя задача эквивалентна генерации случайной перестановки 1...N^2 без дополнительной памяти. Если ты хочешь сэмплить равномерно из всего пространства перестановок, то это невозможно сделать с памятью меньше чем O(N^2). Однако, если честность рандома не очень важна, то ты можешь без проблем сэмплить из подмножества. Например, шагая по i+2 (mod N), если N четно. Но я бы не советовал заниматься таким.

maggotroot
()
Последнее исправление: maggotroot (всего исправлений: 2)

В случайном порядке, без повторений

Не совсем понял, но помоему невозможно, и это очевидно. Если ты перебираешь в случайном порядке, то как убедится, что нет повторения? Как ты себе это представляешь?

terminator-101
()
Ответ на: комментарий от anonymous
for i in 1..N
  for j in i..N
    return (i, j)

молниеносный фикс

anonymous
()

Оставь любые два пункта

  • в случайном порядке
  • без повторений
  • не выделяя память
anonymous
()

Это возможно?

Да. Пусть k — наименьшее натуральное число, такое что 2^k >= N*N. Имея на руках псевдослучайную перестановку k-битных чисел E_k(x), можно сделать цикл от 0 до 2^k - 1, вычисляя y = E_k(x). Частным и остатком вычисляем два числа из y, неподходящие пары отбрасываем.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Имея на руках псевдослучайную перестановку k-битных чисел E_k(x)

откуда же мы её возмём, если она длиннее чем N*(N-1)/2 ?

Indaril_Shpritz
() автор топика

Да, можно.

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

proud_anon ★★★★★
()
Ответ на: комментарий от Indaril_Shpritz

откуда же мы её возмём, если она длиннее чем N*(N-1)/2 ?

Любой блочный шифр — суть псевдослучайная перестановка. Например AES-128 переводит одно 128-битное число в другое 128-битное. Никаких повторений. Вот уже E_128(x) есть. Нужно просто поднапрячь мозг и выдумать псевдослучайную перестановку для чисел нужной битности.

i-rinat ★★★★★
()
Ответ на: комментарий от terminator-101

Если ты перебираешь в случайном порядке, то как убедится, что нет повторения

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

crowbar
()
Ответ на: комментарий от i-rinat

Вот уже E_128(x) есть.

мне это много, у меня N ~= 10^10, будет много промахов

значит надо подбирать M, a и c ближе к ~2^64, причем я до запуска не знаю - сколько.

выдумать псевдослучайную перестановку для чисел нужной битности

надо это делать автоматизированно, компьютером, а не мозгом

Indaril_Shpritz
() автор топика
Ответ на: комментарий от Indaril_Shpritz

значит надо подбирать M

Подбери.

причем я до запуска не знаю - сколько.

Подбери несколько функций, по функции на каждое число бит. Это не так много.

надо это делать автоматизированно, компьютером, а не мозгом

Делай это автоматизированно, компьютером, а не мозгом.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Делай это автоматизированно

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

Берем число S = N*(N-1)/2, ищем M - например следующее простое, большее S. Потом придумываем случайно a и c - они под теорему в любом случае подойдут, если M простое.

проблема в том, что я не знаю, как искать следующее простое, если оно большое. Если M не брать простым, то будут проблемы с выбором a и с

Indaril_Shpritz
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.