For loop over permutations of 1:n with very large n
Mostra commenti meno recenti
Question
Take the following instruction:
for i = 1:1e18
% do something
end
now, probably the execution of the code will take a looong time. I am not concerned with this (see section Context to see why), but with the following problem: consider the instruction
for i = randperm(1e18)
% do something
end
Running the code above returns:
Error using randperm
Requested array exceeds the maximum possible variable size.
My question is: how to perform a for loop over a permutation of the elements of vector 1:n where n is a very large number, without incurring in memory issues? Moreover, how does Matlab perform the first for loop without incurring in such issues?
Context
I am building a simple program with a GUI to solve integer optimization problems. The for loop is used to evaluate the optimization function in the whole search space (which can be very large), and the GUI has a button that the user can press to "break" the loop; when the user does this, the program returns a suboptimal solution of the optimization problem. The second for loop would thus represent a simple implementation of a random search.
2 Commenti
Davide Zorzenon
il 26 Apr 2023
Bruno Luong
il 27 Apr 2023
Modificato: Bruno Luong
il 27 Apr 2023
for i = 1:1e18
% do something
end
Even that simple loop there is a already a problem, since MATLAB cannot store distinct integers up to 1e18, which is beyond the capacity of 53 bits mantissa coding. You don't loop over all integers up to 1e18 as you would expected.
Risposta accettata
Più risposte (1)
Bruno Luong
il 27 Apr 2023
Modificato: Bruno Luong
il 27 Apr 2023
If you don't care about finding optimal solution, why not just do
n = 1e15; % 1e18 has problem of coding as in my comment above
for j = 1:n
i = randi(n);
% do something with i
fprintf('i=%d\n',i);
end
This is more or less has periodicity as Walter comment of LCG (yes behind rand, randi, randperm is Merssene Twister), but collision occurs when compress in smaller range 1:n. But you say you want to find suboptimal solution,so collision should only have negligible impact to runing time and not on randomness covering.
5 Commenti
Davide Zorzenon
il 27 Apr 2023
Modificato: Davide Zorzenon
il 27 Apr 2023
Bruno Luong
il 27 Apr 2023
Modificato: Bruno Luong
il 27 Apr 2023
I assume you have very large n and user stops by push button in your Context description.
For small n, just loop a little bit more so the chance of full cover increases.
OK my solution gives collision in generated number so it is far from being ideal. But it is probably the simplest modification without keeping track of what has been generated and the associated memory issue you encount.
The LCG will have other issues that you must face when n is not prime.
n = 2; % 1e18 has problem of coding as in my comment above
for j = 1:2*n % more than n for better coverage
i = randi(n);
% do something with i
fprintf('i=%d\n',i);
end
n = 10; % 1e18 has problem of coding as in my comment above
for j = 1:2*n
i = randi(n);
% do something with i
fprintf('i=%d\n',i);
end
Davide Zorzenon
il 27 Apr 2023
Bruno Luong
il 27 Apr 2023
Modificato: Bruno Luong
il 27 Apr 2023
Remember my warning: you cannot store in standard matlab double any integer larger than 2^53 ~ 1e16. Let alone doing any meaningful arithmetics and computing prime beyond that.
Walter Roberson
il 27 Apr 2023
https://en.m.wikipedia.org/wiki/Linear-feedback_shift_register
Categorie
Scopri di più su Programming in Centro assistenza e File Exchange
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!