Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate random permutation of huge list (in Python)

I'd like to create a random permutation of the numbers [1,2,...,N] where N is a big number. So I don't want to store all elements of the permutation in memory, but rather iterate over the elements of my particular permutation without holding former values in memory.

Any idea how to do that in Python?

like image 320
Gerenuk Avatar asked Jun 03 '15 09:06

Gerenuk


People also ask

How do you generate random permutations in Python?

To generate random Permutation in Python, then you can use the np random permutation. If the provided parameter is a multi-dimensional array, it is only shuffled along with its first index. If the parameter is an integer, randomly permute np.

How to generate random permutation?

A simple algorithm to generate a permutation of n items uniformly at random without retries, known as the Fisher–Yates shuffle, is to start with any permutation (for example, the identity permutation), and then go through the positions 0 through n − 2 (we use a convention where the first element has index 0, and the ...

How do you randomize the order of items in a list in Python?

Python Random shuffle() Method The shuffle() method takes a sequence, like a list, and reorganize the order of the items. Note: This method changes the original list, it does not return a new list.

What is numpy random permutation?

numpy.random. permutation (x) Randomly permute a sequence, or return a permuted range. If x is a multi-dimensional array, it is only shuffled along its first index.


1 Answers

One possibility is to use an encryption. Since encryption is reversible, i.e. one-to-one, for a given key you will get back the same numbers you encrypt but in a different order.

You need a block cypher with a block size large enough to include your maximum N. Use DES in ECB mode for N = 2^64 - 1. Use AES in ECB mode for N = 2^128 - 1. For other sizes, either use Hasty Pudding cipher, which has variable block size, or write your own simple Feistel cipher. I assume that you just need a shuffle, not a cryptographically secure shuffle.

If the output is greater than N, then just re-encrypt until it is less than N, the 1-to-1 property ensures that the chain of large numbers is also unique.

There is no need to store the entire array in memory, each number can be encrypted as needed. Just the key and the cipher algorithm are needed. One slight complication is that block ciphers work on [0 ... N-1]; you might need some extra code to deal with the extremes.

like image 158
rossum Avatar answered Sep 30 '22 21:09

rossum