Get a permutation as a function of a unique given index in O(n)

2024/10/7 10:24:39

I would like to have a function get_permutation that, given a list l and an index i, returns a permutation of l such that the permutations are unique for all i bigger than 0 and lower than n! (where n = len(l)).

I.e. get_permutation(l,i) != get_permutation(l,j) if i!=j for all i, j s.t. 0 <= i and j < len(l)!).

Moreover, this function has to run in O(n).

For example, this function would comply the with the requirements, if it weren't for the exponential order:

def get_permutation(l, i):return list(itertools.permutations(l))[i]

Does anyone has a solution for the above described problem?

EDIT: I want the permutation from the index NOT the index from the permutation

Answer

If you don't care about which permutations get which indices, an O(n) solution becomes possible if we consider that arithmetic operations with arbitrary integers are O(1).

For example, see the paper "Ranking and unranking permutations in linear time" by Wendy Myrvold and Frank Ruskey.

In short, there are two ideas.


(1) Consider Fisher-Yates shuffle method to generate a random permutation (pseudocode below):

p = [0, 1, ..., n-1]
for i := 0 upto n-1:j := random_integer (0, i)exchange p[i] and p[j]

This transform is injective: if we give it a different sequence of random integers, it is guaranteed to produce a different permutation. So, we substitute random integers by non-random ones: the first one is 0, the second one 0 or 1, ..., the last one can be any integer from 0 to n-1.


(2) There are n! permutations of order n. What we want to do now is to write an integer from 0 to n!-1 in factorial number system: the last digit is always 0, the previous one is 0 or 1, ..., and there are n possibilities from 0 to n-1 for the first digit. Thus we will get a unique sequence to feed the above pseudocode with.

Now, if we consider division of our number by an integer from 1 to n to be O(1) operation, transforming the number to factorial system is O(n) such divisions. This is, strictly speaking, not true: for large n, the number n! contains on the order of O(n log n) binary digits, and that division's cost is proportional to the number of digits.


In practice, for small n, O(n^2) or O(n log n) methods to rank or unrank a permutation, and also methods requiring O(2^n) or O(n!) memory to store some precomputed values, may be faster than an O(n) method involving integer division, which is a relatively slow operation on modern processors. For n large enough so that the n! does not fit into a machine word, the "O(n) if order-n! integer operations are O(1)" argument stops working. So, you may be better off for both small and large n if you don't insist on it being theoretically O(n).

https://en.xdnf.cn/q/70251.html

Related Q&A

How to generate Bitcoin keys/addresses from a seed in Python?

I am trying to create a set of public/private keys from a mnemonic based on BIP0039. I am working in Python.Here is the code I have so far:from mnemonic import Mnemonic mnemon = Mnemonic(english) words…

NumPy - Set values in structured array based on other values in structured array

I have a structured NumPy array:a = numpy.zeros((10, 10), dtype=[("x", int),("y", str)])I want to set values in a["y"] to either "hello" if the corresponding val…

numpy.disutils.system_info.NotFoundError: no lapack/blas resources found

Problem: Linking numpy to correct Linear Algebra libraries. Process is so complicated that I might be looking for the solution 6th time and I have no idea whats going wrong. I am on Ubuntu 12.04.5. I …

Opencv: Jetmap or colormap to grayscale, reverse applyColorMap()

To convert to colormap, I doimport cv2 im = cv2.imread(test.jpg, cv2.IMREAD_GRAYSCALE) im_color = cv2.applyColorMap(im, cv2.COLORMAP_JET) cv2.imwrite(colormap.jpg, im_color)Then,cv2.imread(colormap.jpg…

Get file modification time to nanosecond precision

I need to get the full nanosecond-precision modified timestamp for each file in a Python 2 program that walks the filesystem tree. I want to do this in Python itself, because spawning a new subprocess …

`TypeError: argument 2 must be a connection, cursor or None` in Psycopg2

I have a heroku pipeline set up, and have just enabled review apps for it. It is using the same codebase as my staging and production apps, same settings files and everything.When the review app spins …

replace string if length is less than x

I have a dataframe below. a = {Id: [ants, bees, cows, snakes, horses], 2nd Attempts: [10, 12, 15, 14, 0],3rd Attempts: [10, 10, 9, 11, 10]} a = pd.DataFrame(a) print (a)I want to able add text (-s) to …

Convert ast node into python object

Given an ast node that can be evaluated by itself, but is not literal enough for ast.literal_eval e.g. a list comprehensionsrc = [i**2 for i in range(10)] a = ast.parse(src)Now a.body[0] is an ast.Expr…

Keras custom loss function (elastic net)

Im try to code Elastic-Net. Its look likes:And I want to use this loss function into Keras:def nn_weather_model():ip_weather = Input(shape = (30, 38, 5))x_weather = BatchNormalization(name=weather1)(ip…

Django Models / SQLAlchemy are bloated! Any truly Pythonic DB models out there?

"Make things as simple as possible, but no simpler."Can we find the solution/s that fix the Python database world?Update: A lustdb prototype has been written by Alex Martelli - if you know a…