MATLAB - 创建唯一对的二维数组的最佳方法是什么?

7
在Matlab中创建一个10x2的矩阵,其中每个元素是1-5之间的随机整数,并且这个数组中只有唯一的元素对,这该怎么做呢?我知道randperm可以给我随机的唯一数字,但我不确定是否可以使用randperm来提供唯一的元素对?我能想到的另一种方法是使用:
randi([1 5], 10, 2);

在一个循环中,使用if语句检查是否所有的对都是唯一的。我想要的数据示例可能是:

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

注意:元素的顺序不重要,例如,4、5和5、4都是有效的。

3
nchoosek 是 MATLAB 中的一个函数,用于计算从 $n$ 个元素中选择 $k$ 个元素的组合数。 - sco1
虽然这是一个奇怪的问题。如果你随机选择1到5之间的整数,不能保证你会得到10个唯一的值对。唯一保证的方法是只使用1-5作为输入整数。 - sco1
[1,2;2,1] 是否允许? - Daniel
@Daniel 是的,他说元素的顺序并不重要。 - sco1
@excaza:但如果顺序不重要,我会认为它是一个重复项,不应该被允许。 - Daniel
显示剩余2条评论
3个回答

5
首先将所有可能的配对生成为矩阵的行,然后使用randperm生成随机子集的行索引:
N = 5;                                    %// alphabet size
M = 2;                                    %// number of columns
P = 10;                                   %// desired number of rows
allPairs = dec2base(0:N^M-1, N)-'0'+1;    %// generate all possible rows
ind = randperm(size(allPairs,1));         %// indices for random permutation of rows
ind = ind(1:P);                           %// pick P unique indices
result = allPairs(ind,:);                 %// use those indices to select rows

例子结果:

result =
     3     2
     1     4
     3     5
     4     1
     1     3
     1     2
     2     4
     3     4
     5     5
     1     5

根据那些函数又发布了一个,希望没问题 :) - Divakar

3

这里有另一种方法,使用randpermdec2base,而不会产生生成所有可能行的内存开销(引用Luis的解决方案) -

%// Inputs
start = 1
stop = 5
Nr  = 10                    %// Number of rows needed
Nc = 2                      %// Number of cols needed

intv = stop - start + 1;                    %// Interval/range of numbers
rand_ID = randperm(power(intv,Nc)-1,Nr);    %// Unique IDs
out = dec2base(rand_ID,intv) - '0'+ start   %// 2D array of unique numbers

示例运行:

案例 #1(与问题中列出的参数相同):

start =
     1
stop =
     5
Nr =
    10
Nc =
     2
out =
     1     3
     2     1
     5     3
     5     4
     5     5
     3     4
     2     3
     2     5
     3     3
     1     4

案例 #2(不同参数):

start =
        1025
stop =
        1033
Nr =
    10
Nc =
     5
out =
        1030        1029        1033        1028        1029
        1033        1029        1026        1025        1025
        1028        1026        1031        1028        1030
        1028        1031        1027        1028        1025
        1033        1032        1031        1029        1032
        1033        1029        1030        1027        1028
        1031        1025        1032        1027        1025
        1033        1033        1025        1028        1029
        1031        1033        1025        1033        1029
        1028        1025        1027        1028        1032

请注意,dec2base仅适用于2 <= intv <= 36,请参见dec2base。(如何在注释中缩短链接?) - user2457516
@FirefoxMetzger some_text 没有空格。是的,我想这里有一个限制,谢谢提供信息! - Divakar

1

根据excaza的评论,我发现这个符合我的需求:

n = randperm(5);
k = 2;
data = nchoosek(n, k);

这提供了一些示例输出:

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

但这只为每对给出了一种可能的排序方式。例如,如果输出中存在“1 2”,则保证永远不会出现“2 1”。此外,您永远不会得到两个相等值的行。特别地,您在答案中给出的示例输出永远不会发生。要么您的问题表述不清,要么这个答案是错误的。我认为是这个答案有误,所以很抱歉,我要给它点踩。 - Luis Mendo

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