生成某些排列

时间:2014-10-27 20:30:24

标签: algorithm matlab matrix permutation

我有2个变量......输入数N和历史M的长度。这两个变量决定矩阵V的大小,即n x m,即n行,m列。

我很难想出一种算法,它可以让我生成一定数量的排列(或序列,你认为合适的方式)。

如果有人可以帮助我使用算法,我会很高兴,如果可能的话,在Matlab中,但伪算法也会非常好。

我举三个例子:

  1. 如果输入的数量是N = 1并且历史的长度是M = 2,则我有(M + 1)^ N个不同的组合,在这种情况下为3.排列为:
  2. (如果您不熟悉matlab矩阵表示法,,分隔列,;分隔行。)

    V(1) = [1,0,0] 
    V(2) = [0,1,0]
    V(3) = [0,0,1]
    
    1. 如果输入的数量是N = 2并且历史的长度是M = 2,我有(M + 1)^ N个不同的组合,在这种情况下为9。
    2. 排列是:

      V(1) = [1,0,0; 1,0,0]
      V(2) = [1,0,0; 0,1,0]
      V(3) = [1,0,0; 0,0,1]
      V(4) = [0,1,0; 1,0,0]
      V(5) = [0,1,0; 0,1,0]
      V(6) = [0,1,0; 0,0,1]
      V(7) = [0,0,1; 1,0,0]
      V(8) = [0,0,1; 0,1,0]
      V(9) = [0,0,1; 0,0,1]
      
      1. 如果输入的数量是N = 3并且历史的长度是M = 3,我有(M + 1)^ N个不同的组合,在这种情况下是64。
      2. 排列是:

        V(1)  = [1,0,0,0; 1,0,0,0; 1,0,0,0] 
        V(2)  = [1,0,0,0; 1,0,0,0; 0,1,0,0]
        V(3)  = [1,0,0,0; 1,0,0,0; 0,0,1,0]
        V(4)  = [1,0,0,0; 1,0,0,0; 0,0,0,1]
        V(5)  = [1,0,0,0; 0,1,0,0; 1,0,0,0]
                ...
        V(8)  = [1,0,0,0; 0,1,0,0; 0,0,0,1]
        V(9)  = [1,0,0,0; 0,0,1,0; 1,0,0,0]
                ...
        V(16) = [1,0,0,0; 0,0,0,1; 0,0,0,1]
        V(17) = [0,1,0,0; 1,0,0,0; 1,0,0,0]
                ...
        V(64) = [0,0,0,1; 0,0,0,1; 0,0,0,1]
        

        编辑:我刚刚找到了一种方法来生成非常大的矩阵W,其中每一行代表V(i)

        对于第一种情况:

        W = eye(3)
        

        此处eye(k)创建大小为k x k

        的单位矩阵

        对于第二种情况:

        W = [kron(eye(3),    ones(3,1)), ...
             kron(ones(3,1),    eye(3))]
        

        此处kron是大小为k x l的kronecker productones(k,l) creates a matrix with ones

        对于第三种情况:

        W = [kron(kron(eye(4),    ones(4,1)), ones(4,1)), ...
             kron(kron(ones(4,1),    eye(4)), ones(4,1)), ...
             kron(kron(ones(4,1), ones(4,1)),    eye(4))]
        

        现在我们创建了矩阵W,其中每行代表矢量形式的V(i),V(i)还不是矩阵。

        观察两件事:

        1. 当输入N增加时,额外的列会添加额外的kronecker积,并且单位矩阵会沿着向量移动。
        2. 当历史M的长度增加时,同一性矩阵向量增加,例如,眼睛(4) - >眼睛(5),(4,1) - >酮(5,1)。

3 个答案:

答案 0 :(得分:3)

我想这可以满足您的所有要求。即使订单对我来说也是正确的:

M=3;N=3;
mat1=eye(M+1);
vectors=mat2cell(repmat(1:M+1,N,1),ones(N,1),[M+1]);

超高效笛卡尔积,取自here

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
n = numel(vectors); %// number of vectors
combs = cell(1,n); %// pre-define to generate comma-separated list
[combs{end:-1:1}] = ndgrid(vectors{end:-1:1}); %// the reverse order in these two
%// comma-separated lists is needed to produce the rows of the result matrix in
%// lexicographical order
combs = cat(n+1, combs{:}); %// concat the n n-dim arrays along dimension n+1
combs = reshape(combs,[],n); %// reshape to obtain desired matrix
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    

V=cell(size(combs,1),1);
for i=1:size(combs,1)
    for j=1:size(combs,2)
        V{i,1}=[V{i,1};mat1(combs(i,j),:)];
    end
end

输出:

M=2,N=2;

V=

[1,0,0;1,0,0]
[1,0,0;0,1,0]
[1,0,0;0,0,1]
[0,1,0;1,0,0]
[0,1,0;0,1,0]
[0,1,0;0,0,1]
[0,0,1;1,0,0]
[0,0,1;0,1,0]
[0,0,1;0,0,1]

M=3;N=3;  %order verified for the indices given in the question

V(1)  = [1,0,0,0; 1,0,0,0; 1,0,0,0] 
V(2)  = [1,0,0,0; 1,0,0,0; 0,1,0,0]
V(3)  = [1,0,0,0; 1,0,0,0; 0,0,1,0]
V(4)  = [1,0,0,0; 1,0,0,0; 0,0,0,1]
V(5)  = [1,0,0,0; 0,1,0,0; 1,0,0,0]
        ...
V(8)  = [1,0,0,0; 0,1,0,0; 0,0,0,1]
V(9)  = [1,0,0,0; 0,0,1,0; 1,0,0,0]
        ...
V(16) = [1,0,0,0; 0,0,0,1; 0,0,0,1]
V(17) = [0,1,0,0; 1,0,0,0; 1,0,0,0]
        ...
V(64) = [0,0,0,1; 0,0,0,1; 0,0,0,1]

答案 1 :(得分:2)

您可以通过考虑基数为M + 1的输入来生成这些。

此基数中的每个数字指定矩阵的哪一部分应在每行中设置为1。

function V=makeperm(i,N,M)
i = i - 1;
V = zeros(N,M+1);
P = M+1;
% Generate digits in base P
for row = N:-1:1
    col=mod(i,P)+1;
    i=floor(i/P);
    V(row,col)=1;
end

此函数将为N,M的输入产生第i个排列。

e.g。

makeperm(17,3,3)
ans =

0   1   0   0
1   0   0   0
1   0   0   0

答案 2 :(得分:2)

此代码使用allcomb tool from MATLAB file-exchange生成与V的每一行对应的十进制数字。 allcomb的代码可以从here获得。

解决上述问题的工作代码是 -

power_vals = power(2,M:-1:0);
pattern1 = repmat({power_vals},1,N);
dec_nums = allcomb(pattern1{:});

bin_nums = fliplr(de2bi(num2str(dec_nums,'%1d').'-'0')); %//'
Vout = permute(reshape(bin_nums,N,size(bin_nums,1)/N,[]),[1 3 2]);

因此,nth的{​​{1}} 3D切片将代表Vout

示例运行 -

使用V(n)M = 2,您将拥有 -

N = 2