例如,我有一个矩阵[1,2,3,4,5]'
。这个矩阵包含一列和5行,我必须生成一对像(1,2),(1,3)(1,4)(1,5),(2,3)(2,4)(2,5),(3,4)(3,5)(4,5)
这样的点。
我必须将这些值存储在矩阵的2列中。我有以下代码,但它并没有给我正确的答案。
for s = 1:5;
for tb = (s+1):5;
if tb>s
in = sub2ind(size(pairpoints),(tb-1),1);
pairpoints(in) = s;
in = sub2ind(size(pairpoints),(tb-1),2);
pairpoints(in) = tb;
end
end
end
使用此代码,我得到(1,2),(2,3),(3,4),(4,5)
。我该怎么做,对数的一般公式是什么?
答案 0 :(得分:3)
一种方式,虽然受限于可供选择的不同元素的数量,但是使用nchoosek如下
pairpoints = nchoosek([1:5],2)
pairpoints =
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
在提供的链接中查看此功能的限制。
另一种方法是迭代每个元素并将其与列表中的其余元素组合(假设所有元素都是不同的)
pairpoints = [];
data = [1:5]';
len = length(data);
for k=1:len
pairpoints = [pairpoints ; [repmat(data(k),len-k,1) data(k+1:end)]];
end
此方法只是将数据中的每个元素与列表中的其余元素连接起来,以获得所需的对。
尝试以上任一方法,看看会发生什么!
答案 1 :(得分:1)
如果您不想依赖nchoosek
,我可以添加的其他建议是生成upper triangular matrix个完整的,忽略对角线,并使用{{3}生成矩阵等于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中使用find
命令,以便我们能够按照您期望的正确顺序进行:
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忍者sortrows
的认可,我从Jon Skeet得到了这个。
因此,你可以试试这个:
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
时才有效。
您希望将此概括为任何值数组。您还希望坚持使用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