Lisp - How to do Random Permutations - lisp

I'm fairly new to Lisp and I was wondering what is the simplest way to create a function that given n returns an array with n elements, with the permutations from 0 to n-1, like for example:
(random-permutations 5)
#(2 4 3 1 0)

Create a vector of length n. Fill it with the consecutive numbers. Shuffle (e. g. Fisher-Yates).
In order to play with all permutations, you might want to take a look at map-permutations from the library alexandria.

Related

How can I use a combination of the min and find functions in Matlab to find how many zeroes are in the vector?

Title says it all. I Know what both of these functions do individually, but combining them is proving difficult.
Collecting all of the answers from the comments, you can do it in a variety of ways:
numel(find(a == min(0))) (à la Try Hard). The min(0) is rather superfluous as you can simply do a == 0, but because you are required to use min, we need that there. The general case is (à la Divakar) numel(find(a == min(abs(a))));. This is assuming that the minimum of a is zero. Essentially, this finds all locations that are zero, and determining how many of these elements are zero is done with numel.
I personally would not use find and min. A.Donda suggests to use sum, which is certainly more elegant... so do: sum(a == 0). a == 0 produces a logical vector where 1 at a position means that the corresponding element at this position in a is 0 and 0 otherwise. We sum up all of the cases where we have 1, which produces how many zero values there are.
This was one I came up with: numel(a) - nnz(a). This comes from the fact that we can decompose the total number of elements in a vector to be the number of zero elements, added with the total of non-zero elements, or nz(a) + nnz(a) = numel(a), and so nz(a) = numel(a) - nnz(a). There is a function in MATLAB called nnz, which counts how many non-zero elements there are in a vector or matrix. Therefore, you can count how many zero elements there are by numel(a) - nnz(a). It's not as elegant as sum(a == 0), but it's certainly another way to achieve what you want.

Retrieve a specific permutation without storing all possible permutations in Matlab

I am working on 2D rectangular packing. In order to minimize the length of the infinite sheet (Width is constant) by changing the order in which parts are placed. For example, we could place 11 parts in 11! ways.
I could label those parts and save all possible permutations using perms function and run it one by one, but I need a large amount of memory even for 11 parts. I'd like to be able to do it for around 1000 parts.
Luckily, I don't need every possible sequence. I would like to index each permutation to a number. Test a random sequence and then use GA to converge the results to find the optimal sequence.
Therefore, I need a function which gives a specific permutation value when run for any number of times unlike randperm function.
For example, function(5,6) should always return say [1 4 3 2 5 6] for 6 parts. I don't need the sequences in a specific order, but the function should give the same sequence for same index. and also for some other index, the sequence should not be same as this one.
So far, I have used randperm function to generate random sequence for around 2000 iterations and finding a best sequence out of it by comparing length, but this works only for few number of parts. Also using randperm may result in repeated sequence instead of unique sequence.
Here's a picture of what I have done.
I can't save the outputs of randperm because I won't have a searchable function space. I don't want to find the length of the sheet for all sequences. I only need do it for certain sequence identified by certain index determined by genetic algorithm. If I use randperm, I won't have the sequence for all indexes (even though I only need some of them).
For example, take some function, 'y = f(x)', in the range [0,10] say. For each value of x, I get a y. Here y is my sheet length. x is the index of permutation. For any x, I find its sequence (the specific permutation) and then its corresponding sheet length. Based on the results of some random values of x, GA will generate me a new list of x to find a more optimal y.
I need a function that duplicates perms, (I guess perms are following the same order of permutations each time it is run because perms(1:4) will yield same results when run any number of times) without actually storing the values.
Is there a way to write the function? If not, then how do i solve my problem?
Edit (how i approached the problem):
In Genetic Algorithm, you need to crossover parents(permutations), But if you crossover permutations, you will get the numbers repeated. for eg:- crossing over 1 2 3 4 with 3 2 1 4 may result something like 3 2 3 4. Therefore, to avoid repetition, i thought of indexing each parent to a number and then convert the number to binary form and then crossover the binary indices to get a new binary number then convert it back to decimal and find its specific permutation. But then later on, i discovered i could just use ordered crossover of the permutations itself instead of crossing over their indices.
More details on Ordered Crossover could be found here
Below are two functions that together will generate permutations in lexographical order and return the nth permutation
For example, I can call
nth_permutation(5, [1 2 3 4])
And the output will be [1 4 2 3]
Intuitively, how long this method takes is linear in n. The size of the set doesn't matter. I benchmarked nth_permutations(n, 1:1000) averaged over 100 iterations and got the following graph
So timewise it seems okay.
function [permutation] = nth_permutation(n, set)
%%NTH_PERMUTATION Generates n permutations of set in lexographical order and
%%outputs the last one
%% set is a 1 by m matrix
set = sort(set);
permutation = set; %First permutation
for ii=2:n
permutation = next_permute(permutation);
end
end
function [p] = next_permute(p)
%Following algorithm from https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
%Find the largest index k such that p[k] < p[k+1]
larger = p(1:end-1) < p(2:end);
k = max(find(larger));
%If no such index exists, the permutation is the last permutation.
if isempty(k)
display('Last permutation reached');
return
end
%Find the largest index l greater than k such that p[k] < p[l].
larger = [false(1, k) p(k+1:end) > p(k)];
l = max(find(larger));
%Swap the value of p[k] with that of p[l].
p([k, l]) = p([l, k]);
%Reverse the sequence from p[k + 1] up to and including the final element p[n].
p(k+1:end) = p(end:-1:k+1);
end

How to generate unique random numbers in Matlab?

I need to generate m unique random numbers in range 1 to n. Currently what I have implemented is:
round(rand(1,m)*(n-1)+1)
However, some numbers are repeated in the array. How can I get only unique numbers?
You can use randperm.
From the description:
p = randperm(n,k) returns a row vector containing k unique integers
selected randomly from 1 to n inclusive.
Thus, randperm(6,3)
might be the vector
[4 2 5]
Update
The two argument version of randperm only appeared in R2011b, so if you are using an earlier version of MATLAB then you will see that error. In this case, use:
A = randperm(n);
A = A(1:m);
As pointed out above, in Matlab versions older than R2011b randperm only accepts one input argument. In that case the easiest approach, assuming you have the Statistics Toolbx, is to use randsample:
randsample(n,m)
The randperm approach described by #Stewie appears to be the way to go in most cases. However if you can only use Matlab with 1 input argument and n is really large, it may not be feasible to use randperm on all numbers and select the first few. In this case here is what you can do:
Generate an integer between 1 and n
Generate an integer between 1 and n-1, this is the choice out of the available integers.
Repeat until you have m numbers
This can be done with randi and could even be vectorized by just drawing a lot of random numbers at each step until the unique amount is correct.
Use Shuffle, from the MATLAB File Exchange.
Index = Shuffle(n, 'index', m);
This can be done by sorting a random vector of floats:
[i,i]=sort(rand(1,range));
output=i(1:m);

Assigning the different row to another matrix after comparing two matrices

i have two matrices
r=10,000x2
q=10,000x2
i have to find out those rows of q which are one value or both values(as it is a two column matrix) different then r and allocate them in another matrix, right now i am trying this.i cannot use isequal because i want to know those rows
which are not equal this code gives me the individual elements not the complete rows different
can anyone help please
if r(:,:)~=q(:,:)
IN= find(registeredPts(:,:)~=q(:,:))
end
You can probably do this using ismember. Is this what you want? Here you get the values from q in rows that are different from r.
q=[1,2;3,4;5,6]
r=[1,2;3,5;5,6]
x = q(sum(ismember(q,r),2) < 2,:)
x =
3 4
What this do:
ismember creates an array with 1's in the positions where q == r, and 0 in the remaining positions. sum(.., 2) takes the column sum of each of these rows. If the sum is less than 2, that row is included in the new array.
Update
If the values might differ some due to floating point arithmetic, check out ismemberf from the file exchange. I haven't tested it myself, but it looks good.

How to generate all possible combinations n-bit strings?

Given a positive integer n, I want to generate all possible n bit combinations in matlab.
For ex : If n=3, then answer should be
000
001
010
011
100
101
110
111
How do I do it ?
I want to actually store them in matrix. I tried
for n=1:2^4
r(n)=dec2bin(n,5);
end;
but that gave error "In an assignment A(:) = B, the number of elements in A and B must be the same.
Just loop over all integers in [0,2^n), and print the number as binary. If you always want to have n digits (e.g. insert leading zeros), this would look like:
for ii=0:2^n-1,
fprintf('%0*s\n', n, dec2bin(ii));
end
Edit: there are a number of ways to put the results in a matrix. The easiest is to use
x = dec2bin(0:2^n-1);
which will produce an n-by-2^n matrix of type char. Each row is one of the bit strings.
If you really want to store strings in each row, you can do this:
x = cell(1, 2^n);
for ii=0:2^n-1,
x{ii} = dec2bin(ii);
end
However, if you're looking for efficient processing, you should remember that integers are already stored in memory in binary! So, the vector:
x = 0 : 2^n-1;
Contains the binary patterns in the most memory efficient and CPU efficient way possible. The only trade-off is that you will not be able to represent patterns with more than 32 of 64 bits using this compact representation.
This is a one-line answer to the question which gives you a double array of all 2^n bit combinations:
bitCombs = dec2bin(0:2^n-1) - '0'
So many ways to do this permutation. If you are looking to implement with an array counter: set an array of counters going from 0 to 1 for each of the three positions (2^0,2^1,2^2). Let the starting number be 000 (stored in an array). Use the counter and increment its 1st place (2^0). The number will be 001. Reset the counter at position (2^0) and increase counter at 2^1 and go on a loop till you complete all the counters.