how to produce every permutation of positioning 20 values of -1 in a 1-by-41 vector of ones?

牧云@^-^@ 提交于 2019-12-31 04:50:11

问题


I have written different code to produce different permutations of ones and minus ones. they work for matrixes with small dimensions:

for example:

S=[-1 -1 1 1 1 1 1 1];
P=unique(perms(S),'rows');

produces:

-1  -1   1   1   1   1   1   1
-1   1  -1   1   1   1   1   1
-1   1   1  -1   1   1   1   1
-1   1   1   1  -1   1   1   1
-1   1   1   1   1  -1   1   1
-1   1   1   1   1   1  -1   1
-1   1   1   1   1   1   1  -1
 1  -1  -1   1   1   1   1   1
 1  -1   1  -1   1   1   1   1
 1  -1   1   1  -1   1   1   1
 1  -1   1   1   1  -1   1   1
 1  -1   1   1   1   1  -1   1
 1  -1   1   1   1   1   1  -1
 1   1  -1  -1   1   1   1   1
 1   1  -1   1  -1   1   1   1
 1   1  -1   1   1  -1   1   1
 1   1  -1   1   1   1  -1   1
 1   1  -1   1   1   1   1  -1
 1   1   1  -1  -1   1   1   1
 1   1   1  -1   1  -1   1   1
 1   1   1  -1   1   1  -1   1
 1   1   1  -1   1   1   1  -1
 1   1   1   1  -1  -1   1   1
 1   1   1   1  -1   1  -1   1
 1   1   1   1  -1   1   1  -1
 1   1   1   1   1  -1  -1   1
 1   1   1   1   1  -1   1  -1
 1   1   1   1   1   1  -1  -1

or

indices = nchoosek(1:41, 6);
N = size(indices, 1);
S = ones(N, 41);
S(sub2ind([N 41], [1:N 1:N 1:N 1:N 1:N 1:N].', indices(:))) = -1;

can produce a matrix of 4496388_by_41 of all the permutations of 6 minus one(-1) and 35 one(1).

these codes work for smaller dimensions but they don't work for the matrixs with larger dimensions.

my goal is to produce all permutations of 20 minus one(-1) and 21 one(1) this matrix has 269128937220 rows and 41 columns. but the following codes don't work:

indices = nchoosek(1:41, 20);
N = size(indices, 1);
S = ones(N, 41);
S(sub2ind([N 41], [1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N].', indices(:))) = -1;

or

S=[-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1];
P=unique(perms(S),'rows');

I do a simple calculation on each permutation(each row of this matrix). if I could write each row of this matrix with for loops and then do the calculation on that row, I would be able to keep the best result and in this situation I wouldn't have to keep all these data in the memory and I wouldn't get out of memory errors from matlab.

if you know how to produce a matrix of all the permutations of 20 minus one(-1) and 21 one(1) with for loops or any other way to store them in my computer please help.

thanks in advance


回答1:


I'm not an expert in Matlab so I can't speak for all of the resources available, however, I know that your task is feasible on a standard laptop without any fancy high performance services such as https://aws.amazon.com/hpc/.

I have authored a package in R called RcppAlgos that is capable of completing this task comfortably in a few hours. Here is the code:

options(scipen = 999)
library(parallel)
library(RcppAlgos)

## WARNING Don't run this unless you have a few hours on your hand

## break up into even intervals of one million
firstPart <- mclapply(seq(1, 269128000000, 10^6), function(x) {
    temp <- permuteGeneral(c(1L,-1L), freqs = c(21,20), lower = x, upper = x + 999999)
    ## your analysis here
    x
}, mc.cores = 8)

## get the last few results and complete analysis
lastPart <- permuteGeneral(c(1L, -1L), freqs = c(21, 20), 
                           lower = 269128000000, upper = 269128937220)
## analysis for last part goes here

And to give you a demonstration of the efficiency of this setup, we will demonstrate how fast the first one billion results are completed.

system.time(mclapply(seq(1, 10^9, 10^6), function(x) {
    temp <- permuteGeneral(c(1L, -1L), freqs = c(21, 20), lower = x, upper = x + 999999)
    ## your analysis here
    x
}, mc.cores = 8))

   user  system elapsed 
121.158  64.057  27.182

Under 30 seconds for 1000000000 results!!!!!!!

So, this will not take over 3000 days as @CrisLuengo calculated but rather a conservative estimate of 30 seconds per billion gives :

(269128937220 / 1000000000 / 60) * 30 ~= 134.5645 minutes

I should also note that with the setup above you are only using 1251.2 Mb at a time, so your memory will not explode.

testSize <- object.size(permuteGeneral(c(1L,-1L), freqs = c(21,20), upper = 1e6))
print(testSize, units = "Mb")
156.4 Mb ## per core

All results were obtained on a MacBook Pro 2.8GHz quad core (with 4 virtual cores.. 8 total).

Edit:

As @CrisLuengo points out, the above only measures generating that many permutations and does not factor in the time taken for analysis of each computation. After some more clarification and a new question, we have that answer now... about 2.5 days!!!



来源:https://stackoverflow.com/questions/51564122/how-to-produce-every-permutation-of-positioning-20-values-of-1-in-a-1-by-41-vec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!