消除矩阵中相同的排列,Matlab

消除矩阵中相同的排列,Matlab,matlab,permutation,Matlab,Permutation,我用Matlab生成了一个X×10的数字数组。此数组“精神上”分为4、3和3列。如果下面给出了此数组,则为两行 [1234;567;8910] [1234;8910;567] 分号是精神分裂。我需要进一步处理这个数组,但是“心智列”排列提供了相同的信息。第二行是第一行的第二行和第三行的排列 有什么简单的方法可以用Matlab的内置函数消除排列吗?有点像一个能识别排列的唯一的。这并不比将数字转换成数字序列好多少。但这是相同的想法,即将数字组映射到唯一标识符。这是我的密码 M=[1 2 3 4 5

我用Matlab生成了一个X×10的数字数组。此数组“精神上”分为4、3和3列。如果下面给出了此数组,则为两行

[1234;567;8910]
[1234;8910;567]

分号是精神分裂。我需要进一步处理这个数组,但是“心智列”排列提供了相同的信息。第二行是第一行的第二行和第三行的排列


有什么简单的方法可以用Matlab的内置函数消除排列吗?有点像一个能识别排列的唯一的。

这并不比将数字转换成数字序列好多少。但这是相同的想法,即将数字组映射到唯一标识符。这是我的密码

M=[1 2 3 4 5 6 7 8 9 10;1 2 3 4 8 9 10 5 6 7;5 6 7 8 9 10 11 1 2 3;5 6 7 8 1 2 3 9 10 11];
%chop matrix into mental columns
M4=M(:,1:4);
M3=[M(:,5:7);M(:,8:10)]; % stack the 3s together

[u_M4,ia_M4,ic_M4]=unique(M4,'rows');% give each unique row of 4 a one digit id 
[u_M3,ia_M3,ic_M3]=unique(M3,'rows');% give each unique row of 3 a one digit id 
idx3=[ic_M3(1:length(ic_M3)/2) ic_M3(length(ic_M3)/2+1:end)]; % reshape the ids for the 3 so it matches the original format
sort_idx3=sort(idx3,2); % sort
idx=[ic_M4 sort_idx3]; % construct the idx matrix consist of the one digit ids
[u_idx,ia_idx,ic_idx]=unique(idx,'rows'); %find of unique id ROWs (that's why we need to sort before)
R=M(ia_idx,:); % now filter the original matrix 

假设您的行存储在矩阵
a
中,列集宽度存储在
len
中(在您的情况下是
len=[4,3,3]
)。首先,我们应该在单元格数组中正确表示此数据:

X = mat2cell(A, ones(size(A, 1), 1), len);
然后我们在这样的单元数组中找到所有可能的列组合(无重复):

现在,对于索引为
r1
r2
X
中给定的两行,我们检查其中一行是否是另一行的排列(即重新排序的“心理”列):

接下来,我们可以找到所有可能的行对(无重复),并针对每对行检查它们是否是彼此的排列:

rows = nchoosek(1:size(A, 1), 2);
N = size(cols, 1);
isperm = @(ii, jj)any(arrayfun(@(n)isequal(X(ii, :), X(jj, cols(n, :))), 1:N));
remove_idx = arrayfun(isperm, rows(:, 1), rows(:, 2));
移除它们非常简单:

A(remove_idx, :) = [];
例子 让我们将以下数据作为输入:

A = [1:10; 11:20; 1:4 8:10 5:7];
len = [4 3 3];
即:

A =
    1    2    3    4    5    6    7    8    9   10
   11   12   13   14   15   16   17   18   19   20
    1    2    3    4    8    9   10    5    6    7

len =
   4   3   3
并运行以下代码:

X = mat2cell(A, ones(size(A, 1), 1), len);
cols = perms(1:numel(len))
rows = nchoosek(1:size(A, 1), 2)
N = size(cols, 1)
isperm = @(ii, jj)any(arrayfun(@(n)isequal(X(ii, :), X(jj, cols(n, :))), 1:N));
remove_idx = arrayfun(isperm, rows(:, 1), rows(:, 2));
A(remove_idx, :) = [];
结果是:

remove_idx =
   0
   1
   0

A =
    1    2    3    4    5    6    7    8    9   10
    1    2    3    4    8    9   10    5    6    7

[1 2 4 3;5 6 7;8 9 10]
是否也会被视为
[1 2 3 4;5 6 7;8 9 10]
的排列?原则上是的,但这些已经被删除。在“心智行”中,排列由构造函数处理。因此解决方案只需要处理“心智”列的排列,对吗?是的,没错。原则上,如果我将数字序列转换成整数(比如1234映射到10203040或类似的东西),然后通过排序和“唯一”消除排列,我可以将这个问题映射到您之前链接的问题上。但这似乎是一个有点乏味的问题:(虽然没有解决这个特定的问题)但是很乐意帮助:记住<>代码> ArayFooy可能是缓慢的,但是对于大的矩阵,你应该考虑用一个for循环来替换它(这可能会更好地加速JIT)…
X = mat2cell(A, ones(size(A, 1), 1), len);
cols = perms(1:numel(len))
rows = nchoosek(1:size(A, 1), 2)
N = size(cols, 1)
isperm = @(ii, jj)any(arrayfun(@(n)isequal(X(ii, :), X(jj, cols(n, :))), 1:N));
remove_idx = arrayfun(isperm, rows(:, 1), rows(:, 2));
A(remove_idx, :) = [];
remove_idx =
   0
   1
   0

A =
    1    2    3    4    5    6    7    8    9   10
    1    2    3    4    8    9   10    5    6    7