首页 > 解决方案 > 在 Matlab 中随机抽取所有可能的索引对

问题描述

考虑一个 Matlab 矩阵B,它列出了所有可能的无序对(没有重复)[1 2 ... n]。例如,如果n=4

B=[1 2;
   1 3;
   1 4;
   2 3;
   2 4;
   3 4]

注意B有大小n(n-1)/2 x 2

我想从中随机抽取mB并将它们存储在一个矩阵C中。继续上面的例子,我可以这样做

m=2;
C=B(randi([1 size(B,1)],m,1),:);

但是,在我的实际情况中,n=371293. 因此,我无法创建B然后运行上面的代码来获取C. 这是因为存储B需要大量内存。

您能否建议我如何在C无需先存储的情况下进行创作B?对不同问题的评论建议

  1. 在和之间绘制随机m整数。1n(n-1)/2

    I=randi([1 n*(n-1)/2],m,1);

  2. 用于ind2sub获取C.

在这里,我正在努力实施第二步。


感谢下面的评论,我写了这个

n=4;
m=10;
coord=NaN(m,2);
R= randi([1 n^2],m,1);
for i=1:m
    [cr, cc]=ind2sub([n,n],R(i));
    if cr>cc
       coord(i,1)=cc;
       coord(i,2)=cr;
    elseif cr<cc
       coord(i,1)=cr;
       coord(i,2)=cc;
    end
end
coord(any(isnan(coord),2),:) = []; %delete NaN rows from coord

我想有更有效的方法来实现同样的事情。

标签: matlab

解决方案


您可以使用本文中命名的函数myind2ind获取所有可能的无序对的随机行,而无需生成所有它们。

function [R , C] = myind2ind(ii, N)
    jj = N * (N - 1) / 2 + 1  - ii;
    r = (1 + sqrt(8 * jj)) / 2;
    R = N  -floor(r);
    idx_first = (floor(r + 1) .* floor(r)) / 2;
    C = idx_first-jj + R + 1;
end

I=randi([1 n*(n-1)/2],m,1);
[C1 C2] = myind2ind (I, n);

推荐阅读