Matlab: 二进制矩阵的所有组合

5
我希望您能提供一个简单的方法来获取二进制矩阵的所有组合。我已经尝试使用函数perms(),但没有得到正确的结果。
例如,我有一个大小为N x N的矩阵,填充了1和-1。当N=2时,可能会有2^4种1和-1的组合,如下所示:
       (1 1)          (1  1)          (-1 -1)
M(1) = (1 1) , M(2) = (1 -1) , M(3) = ( 1  1) and so on...

当我使用perms()函数时,例如第一个矩阵就无法得到。

我该如何解决这个问题?

3个回答

5
你可以用二进制数表示所有介于 02^(N^2)-1 之间的数字,并进行重新排列:
N = 2;
v = (1:2^(N^2))-1;
A = dec2bin(v)' - '0'; %'// Or use: decimalToBinaryVector(v)';
A(A==0) = -1;
A = reshape(A,N,N,2^(N^2));

1
对我来说看起来不错,除了第一行的拼写错误(应该是2^N²-1而不是2^N-1)。此外,我想指出这种方法并不强制你将所有这些组合存储在内存中,因为它给出了矩阵和0:2^N²-1之间的一一对应关系,这意味着如果你只需要随机获取其中一个矩阵,你可以选择一个数字,然后应用等价性。 - BillBokeey
@NKN,根据你的情况,你需要删除一些重复的矩阵;代码为A提供了一个2x2x24的矩阵。(对我来说似乎很容易解决)。至于这个答案,我不知道,它确实为包含1和-1的2x2矩阵提供了所有16种可能性。 - Adriaan
1
@NKN:在你的回答中,“1”和“-1”的数量是固定的。 - Itamar Katz
1
看起来decimalToBinaryVector是Data Acquisition Toolbox特有的。我相信你可以使用A=(dec2bin(v)-'0').'; 来实现同样的功能。 - Andras Deak -- Слава Україні
2
@AndrasDeak:我记得有一个函数可以做到这一点,但由于某种原因,在Matlab的文档中搜索时给出了decimalToBinaryVector。我会编辑我的答案。谢谢! - Itamar Katz
显示剩余2条评论

-1
一个简单的技巧如下:
v = [1 -1 1 -1];
P = perms(v);
for ii = 1:size(P,1)
    A = reshape(P(ii,:),2,2)
end

这将导致:

A =

    -1    -1
     1     1

...

结果中仍然有一些相同的矩阵需要被移除。


1
使用您的方法,我无法获得具有超过两个1或-1的矩阵。 - Gilfoyle
你只会得到由两个 -1 和两个 1 组成的矩阵。为了去除重复项,我建议使用一行代码 P = unique(P,'rows') 来消除重复项。 - Adriaan

-1

我认为我找到了解决我的问题的方法

L = 2;
N = L^2;
v = cell(N,1);
for k = 1:N
    v{k} = linspace(-1,1,2);
end

ne=numel(v);
x=cell(ne,1);
[x{1:ne,1}]=ndgrid(v{end:-1:1});
p=reshape(cat(ne+1,x{:}),[],ne);

F = cell(length(p),1);
for k=1:length(p)
    F{k} = reshape(p(k,:),L,L);
end

两件事:请不要在 SO 代码中使用 clear all,因为人们倾向于将这些代码复制到自己的代码中,而 clear 调用会搞乱一切。第二点:p 是一个 65536x16 的双精度浮点数,这对于您的排列来说似乎有些大了。所有所需的排列都在里面,但是太多了。我认为您在尺寸方面有些过分了。 - Adriaan
另外,“v”只是一个16x1的单元格,其中包含16个相同的矩阵:“[-1 1]”。整个循环只是一种困难的方式来编写这两个数字。(顺便说一下,我没有对这个答案投票) - Adriaan
我现在已经对回答点了踩,因为虽然你删除了 clear,但这不是解决方案错误的主要问题。只需运行它,你就会发现 v 包含16个矩阵,每个矩阵都是 [-1 1],而且 p 比你需要的要大得多。这使得这个答案无法使用。 - Adriaan
@Adriaan 现在应该没问题了。你能看一下吗? - Gilfoyle
现在是正确的,但你仍然有一个奇怪的v赋值,可以查看之前的评论以了解说明。这导致x的所有单元格都包含重复的矩阵,使得此代码效率不高。另外,我建议不要使用单元格来存储F,而是使用3D数组,如下所示:F(:,:,k) = reshape(p(k,:),L,L);总的来说,它能工作,但不够美观也不够高效。尽管如此,我已经取消了踩的操作,因为它确实能工作。 - Adriaan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接