Is there an efficient way to create a matrix with all permutations of inserting one array into another?

조회 수: 1 (최근 30일)
Hi!
In order to compute the fitness of a specific population with genetic algorithm, I need to generate the population first.
In my case, every chromosome should be created by concatenating 2 partial sub-chromosomes as following:
The 1st sub-chromosome is called as reversing chromosome, which is a flipping left to right of part of an existing array, e.g., the initial array is [1:1:6] and the part of it is selected as [2, 3, 4], thus the reversing chromosome should be [4, 3, 2];
The 2nd sub-chromosome is called as remaining chromosome, which is the subtraction of full array, saying, [1:1:6], and the partial array as mentioned above, [2, 3, 4], thus the remaining chromosome here should be [1, 5, 6];
Next, by inserting the 1st sub-chromosome to every possible position among the 2nd sub-chromosome, saying, the 4 potential spots occupied by "^" of the 2nd sub-chromosome
[ ^, 1, 5, 6 ]
[ 1, ^, 5, 6 ]
[ 1, 5, ^, 6 ]
[ 1, 5, 6, ^ ]
This operation provides 4 chromosomes that I do need, as following:
[ 4, 3, 2, 1, 5, 6 ]
[ 1, 4, 3, 2, 5, 6 ]
[ 1, 5, 4, 3, 2, 6 ]
[ 1, 5, 6, 4, 3, 2 ]
I wrote some codes which worked but they were cumbersome and inefficient:
InitialChromosome = [1:1:6];
poscut1 = 4;
poscut2 = 2;
reverseChromosome = fliplr( InitialChromosome( min([poscut1,poscut2]):1:max([poscut1,poscut2]) ) );
remainingChromosome = InitialChromosome( [1:1:min([poscut1,poscut2])-1,max([poscut1,poscut2])+1:1:end] );
[LB,Ld] = spdiags( tril( ones(length(remainingChromosome),1)*remainingChromosome ) );
[UB,Ud] = spdiags( triu( ones(length(remainingChromosome),1)*remainingChromosome ) );
D = ones(length(remainingChromosome)+1, 1 )*reverseChromosome;
tempMatrix = [[zeros(1,length(remainingChromosome));fliplr( spdiags(LB) )],D,[fliplr( spdiags(UB) );zeros(1,length(remainingChromosome))]];
tempIdx = [Ld-1;[0:1:length(reverseChromosome)-1]';Ud+length(reverseChromosome)];
Population = full( spdiags( tempMatrix,tempIdx,length(remainingChromosome)+1, length(InitialChromosome) ) )
And I also found a way to use the function arrayfun like
tempMatrix = arrayfun(@(ii) [remainingChromosome(1:1:ii-1), reverseChromosome, remainingChromosome(ii:1:end)]', [1:1:length( remainingChromosome )+1] ,'UniformOutput',false);
Population = horzcat(tempMatrix{:})'
Is there any way to create the whole population matrix directly, or more efficiently?
I am not sure if my objective matrix is one of the specific matrix forms such as Toeplitz or Circulant Matrix that could be generated easily with a single built-in command.
Please don't hesitate to post your advices. Any suggestions would be appreciated!
Thanks!

채택된 답변

Stephen23
Stephen23 2019년 1월 14일
편집: Stephen23 2019년 1월 14일
Perhaps something like this:
>> A = [1,5,6]; % remaining
>> B = [4,3,2]; % reversed
>> N = numel(A);
>> M = toeplitz([B,zeros(1,N)],[B(1),zeros(1,N)]);
>> M(M==0) = repmat(A(:),N+1,1);
>> M = M.'
M =
4 3 2 1 5 6
1 4 3 2 5 6
1 5 4 3 2 6
1 5 6 4 3 2
You can probably simplify the selection of those vectors too, e.g.:
mnp = min([poscut1,poscut2]);
mxp = max([poscut1,poscut2]);
B = InitialChromosome(mxp:-1:mnp);
A = InitialChromosome([1:mnp-1,mxp+1:end]);

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Creating and Concatenating Matrices에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by