让我用一个例子来解释:如果我给'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修改,我将得到对索引。我试图将这对索引转换成一对。很抱歉没有解释所有这些。希望我很清楚。
答案 0 :(得分:2)
如果你想要一个同样适用于大N的高效算法,这应该做到(并且很好地根据均匀分布):
您的第一个号码是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