Я хочу знать, теоретически возможно ли объяснение, описанное ниже, и если да, то как я могу это сделать.
Вам предоставляется пространство элементов N (т.е. все числа между 0 и N-1.). Посмотрите на пространство всех перестановок в этом пространстве и назовите его S. i -й член S, который может быть помечен S[i], является перестановкой с лексикографическим номером i.
Например, если N равно 3, то S - это список перестановок:
S[0]: 0, 1, 2
S[1]: 0, 2, 1
S[2]: 1, 0, 2
S[3]: 1, 2, 0
S[4]: 2, 0, 1
S[5]: 2, 1, 0
(Конечно, при просмотре большого N это пространство становится очень большим, N!, если быть точным.)
Теперь я уже знаю как получить перестановку по его номеру индекса i, и я уже знаю, как сделать обратное (получить лексикографическое число данной перестановки. ) Но я хочу что-то лучше.
Некоторые перестановки могут быть огромными сами по себе. Например, если вы смотрите на N=10^20. (Размер S будет (10^20)!, который, я считаю, является самым большим числом, которое я когда-либо упоминал в вопросе:)
Если вы посмотрите на случайную перестановку в этом пространстве, это будет настолько большим, что вы не сможете сохранить все это на своем жестком диске, не говоря уже о вычислении каждого из элементов по лексикографическому номеру. Я хочу, чтобы иметь возможность доступа к элементам на этой перестановке, а также получить индекс каждого элемента. То есть, заданные N и i для указания перестановки, имеют одну функцию, которая принимает номер индекса и находит номер, который находится в этом индексе, и другую функцию, которая принимает число и находит, в каком индексе он находится. Я хочу сделать это в O(1), поэтому мне не нужно сохранять или перебирать каждый элемент в перестановке.
Сумасшедший, вы говорите? Невозможно? Это может быть. Но учтите это: блочный шифр, такой как AES, по сути является перестановкой, и он почти выполняет задачи, описанные выше. AES имеет размер блока 16 байт, что означает, что N есть 256^16, который находится вокруг 10^38. (Размер S, а не то, что он имеет значение, представляет собой ошеломляющий (256^16)! или около 10^85070591730234615865843651857942052838, который превосходит мою недавнюю запись для "наибольшего числа, упомянутого в переполнении стека":)
Каждый ключ шифрования AES указывает одну перестановку на N=256^16. Эта перестановка не может быть сохранена целиком на вашем компьютере, потому что в ней больше членов, чем в солнечной системе. Но он позволяет вам доступ к элементам. Зашифровывая данные с помощью AES, вы смотрите блок данных по блоку, а для каждого блока (член range(N)) вы выводите зашифрованный блок, член которого range(N), который находится в индексе номера оригинала блок в перестановке. И когда вы расшифровываете, вы делаете обратное (нахождение номера индекса блока.) Я считаю, что это сделано в O(1), я не уверен, но в любом случае это очень быстро.
Проблема с использованием AES или любого другого блочного шифрования заключается в том, что он ограничивает вас очень специфическим N, и он, вероятно, только фиксирует небольшую часть возможных перестановок, в то время как я хочу иметь возможность использовать любой N Мне нравится, и я делаю доступ к элементам любой перестановки S[i], которая мне нравится.
Можно ли получить доступ к элементу O(1) при перестановке, заданный размер N и номер перестановки i? Если да, то как?
(Если мне посчастливилось получить ответы на код здесь, я был бы признателен, если они будут на Python.)
UPDATE
Некоторые люди отметили печальный факт, что само перестановочное число будет настолько огромным, что просто чтение номера сделает задачу невыполнимой. Затем я хотел бы пересмотреть свой вопрос: Учитывая доступ к факадическому представлению лексикографического числа перестановок, можно ли получить любой элемент в перестановке в O (как можно меньше)?