Matlab:获取有序对的列表

时间:2015-05-01 08:48:02

标签: matlab

让我用一个例子来解释:如果我给'4'作为输入,我想要对(1,2),(1,3),(1,4),(2,3),(2, 4),(3,4)在这样的矩阵中:

1 2
1 3
1 4
2 3
2 4
3 4

为什么我需要这个?我将生成一个从1到(n *(n-1)/ 2)的随机数,我想要相应的对。我想我会首先生成配对列表,然后使用随机数作为索引。如果能直接解决这个问题,那就更好了!

编辑: 实际上我不需要所有对,我需要随机有序的对,不重复和第一个值<第二个价值。有5000个列表,每个列表有n个元素。所以可能的总对是tot = 5000 * n *(n-1)/ 2。如果我使用randperm从1到tot生成t随机整数,我可以将它翻译成一对吗?我可以通过除以5000获得列表编号。如果我用5000修改,我将得到对索引。我试图将这对索引转换成一对。很抱歉没有解释所有这些。希望我很清楚。

3 个答案:

答案 0 :(得分:2)

如果你想要一个同样适用于大N的高效算法,这应该做到(并且很好地根据均匀分布):

  1. 生成x作为从1到n-1的数字
  2. 生成y作为从1到n-2的数字
  3. 您的第一个号码是n-1

    如果y< x,你的第二个数字是y,否则是y + 1

    我不确定这是否已实现,但我认为你可以通过matlab实现这一点:

    sort(randsample(4,2))
    

答案 1 :(得分:2)

对于问题的第一部分:您希望一次n=4元素的组合k=2。它有一个功能,即nchoosek

n = 4; %// number of elements
k = 2; %// how many to pick in each group
result = nchoosek(1:n, k);

对于第二部分:这是生成所有有序对的直接方法:

n = 4;
x = randi(n); %// uniformly distributed on {1,2,...,n}
y = randi(n-1);
y = y + (y>=x); %// uniformly distributed on {1,2,...,x-1,x+1,...,n}
pair = sort([x y]);

答案 2 :(得分:0)

由于每行和每列的元素数量不是恒定的,而是线性地保持不变。减少,首先绘制一个随机x,然后是随机y将导致均匀分布x,但非均匀分布(x | y)!由于我认为这个属性很重要,我们需要小心。我将首先绘制一个统一的随机变量i,然后将此连续索引映射到(x | y),如下所示:

x \ y   1   2   3   4
1           #1  #2  #3
2               #4  #5
3                   #6 

即。 (1 | 2)< - > #1等。这当然是可行的。但是因为会导致二次方程和一些舍入,所以有点麻烦。 我建议改为索引完整的“正方形”并跳过对角线错误的一面:

x \ y   1       2       3       4
1       (#1)    #2      #3      #4
2       (#5)    (#6)    #7      #8
3       (#9)    (#10)   (#11)   #12

并在生成时跳过括号中的那些。现在,从索引i(x | y)的函数映射更加简单:

i = (x-1) * N + y

x = floor(i/N) + 1
y = i - (x-1)*N + 1

缺点是,我们永远不能确定我们在对角线的所需侧面上有足够的样本,所以我们需要为此做好准备。 但是,这种可能性非常小。

N = 6 % maximal x and y
S = 10 % number of samples to draw

ind = [];
% This loop will most likely run only once, 
% but we can not be completely sure
while size(ind, 1) < S
    % (*)
    % In order to test uniformity of distribution, we can 
    % generate some repeating data instead of the next line:
    % i = ceil(N*N .* rand(3*S, 1)); 

    % We generate 3*S > S samples, because at least 50% will be removed
    i = randsample(N*N, min(N*N, 3*S)); 

    x = floor(i/N) + 1;
    y = i - x*N + N + 1;

    remove = (x >=  y);
    x(remove, :) = [];
    y(remove, :) = [];

    ind = [x y];
end    
ind = ind(1:S, :);

% verify:
test = accumarray(ind, ones(S,1))

这可能导致

ind =
     2     6
     3     4
     1     4
     3     6
     5     6
     2     3
     1     6
     3     5
     4     6
     1     5   

test =
     0     0     0     1     1     1
     0     0     1     0     0     1
     0     0     0     1     1     1
     0     0     0     0     0     1
     0     0     0     0     0     1

S = 10000的均匀性测试:

test =
     0   671   716   686   691   664
     0     0   644   650   667   664
     0     0     0   672   649   654
     0     0     0     0   667   655
     0     0     0     0     0   650