如果您不想依赖 nchoosek,我可以添加的另一个建议是生成一个充满 1 的 upper triangular matrix,忽略对角线,并使用 find 生成其中矩阵等于 1。然后您可以将这两个连接成一个矩阵。通过以这种方式生成上三角矩阵,它们等于 1 的矩阵位置与您正在寻找的行和列对完全对应。因此:
%// Highest value in your data
N = 5;
[rows,cols] = find(triu(ones(N),1));
pairpoints = [rows,cols]
pairPoints =
1 2
1 3
2 3
1 4
2 4
3 4
1 5
2 5
3 5
4 5
请记住,这将是未排序的(即不是按照您在问题中指定的顺序)。如果顺序对您很重要,请在 MATLAB 中使用 sortrows 命令,以便我们可以按照您期望的正确顺序进行处理:
pairPoints = sortrows(pairPoints)
pairPoints =
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
请注意,我为triu 指定了一个附加参数,它表示您想要远离对角线的偏移量。默认偏移量为 0,其中包括提取上三角矩阵时的对角线。我将 1 指定为第二个参数,因为我想从对角线向右移动 1 个单位,所以我不想将对角线作为上三角分解的一部分。
for循环方法
如果您真的需要 for 循环方法,与您的模型一起使用,您将需要两个 for 循环,并且您需要跟踪我们所在的上一行,以便我们可以直接跳到下一列直到最后使用它。您也可以使用@GeoffHayes 方法,只使用一个for 循环来生成索引,但是当您不熟悉一种语言时,我将始终给出的一个关键建议是编写代码以提高可读性而不是提高效率。一旦你让它工作起来,如果你有一些衡量性能的方法,你就可以尝试让代码更快更高效。这种编程也得到了 StackOverflow 常驻忍者 Jon Skeet 的认可,我是从 this post here 那里得到的。
因此,你可以试试这个:
pairPoints = []; %// Initialize
N = 5; %// Highest value in your data
for row = 1 : N
for col = row + 1 : N
pairPoints = [pairPoints; [row col]]; %// Add row-column pair to matrix
end
end
我们得到等效的输出:
pairPoints =
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
小警告
仅当您的数据从1 枚举到N 时,此方法才有效。
编辑 - 2014 年 8 月 20 日
您希望将此推广到任何值数组。您还想坚持使用for 循环方法。您仍然可以将原始的 for 循环代码保留在那里。您只需添加几行来索引您的新数组。因此,假设您的数据数组是:
dat = [12, 45, 56, 44, 62];
您将使用pairPoints 矩阵并使用每一列对数据数组进行子集化以访问您的值。此外,您需要确保您的数据是列向量,否则这将不起作用。如果我们不这样做,我们将创建一个一维数组并连接行,这显然不是我们正在寻找的。换句话说:
dat = [12, 45, 56, 44, 62];
dat = dat(:); %// Make column vector - Important!
N = numel(dat); %// Total number of elements in your data array
pairPoints = []; %// Initialize
%// Skip if the array is empty
if (N ~= 0)
for row = 1 : N
for col = row + 1 : N
pairPoints = [pairPoints; [row col]]; %// Add row-column pair to matrix
end
end
vals = [dat(pairPoints(:,1)) dat(pairPoints(:,2))];
else
vals = [];
请注意,我已经做出了规定,如果数组为空,则不必费心进行任何计算。只输出一个空矩阵。
因此我们得到:
vals =
12 45
12 56
12 44
12 62
45 56
45 44
45 62
56 44
56 62
44 62