【发布时间】:2016-04-15 13:22:30
【问题描述】:
P 是一个 n*d 矩阵,包含n d 维样本。 P 在某些区域的密度是其他区域的数倍。我想选择P 的一个子集,其中任何一对样本之间的距离都大于d0,并且我需要它遍布整个区域。所有样本都具有相同的优先级,无需优化任何内容(例如覆盖区域或成对距离之和)。
这是一个这样做的示例代码,但它真的很慢。我需要一个更高效的代码,因为我需要多次调用它。
%% generating sample data
n_4 = 1000; n_2 = n_4*2;n = n_4*4;
x1=[ randn(n_4, 1)*10+30; randn(n_4, 1)*3 + 60];
y1=[ randn(n_4, 1)*5 + 35; randn(n_4, 1)*20 + 80 ];
x2 = rand(n_2, 1)*(max(x1)-min(x1)) + min(x1);
y2 = rand(n_2, 1)*(max(y1)-min(y1)) + min(y1);
P = [x1,y1;x2, y2];
%% eliminating close ones
tic
d0 = 1.5;
D = pdist2(P, P);D(1:n+1:end) = inf;
E = zeros(n, 1); % eliminated ones
for i=1:n-1
if ~E(i)
CloseOnes = (D(i,:)<d0) & ((1:n)>i) & (~E');
E(CloseOnes) = 1;
end
end
P2 = P(~E, :);
toc
%% plotting samples
subplot(121); scatter(P(:, 1), P(:, 2)); axis equal;
subplot(122); scatter(P2(:, 1), P2(:, 2)); axis equal;
编辑:子集应该有多大?
正如j_random_hacker 在 cmets 中指出的那样,如果我们不对所选样本的数量进行限制,可以说P(1, :) 是最快的答案。它巧妙地显示了标题的不连贯性!但我认为当前的标题更好地描述了目的。因此,让我们定义一个约束:“如果可能,请尝试选择 m 样本”。现在有了m=n 的隐含假设,我们可以获得最大可能的子集。正如我之前提到的,一种更快的方法优于找到最佳答案的方法。
【问题讨论】:
-
请注意,在
pdist2(P, P)中计算距离会占用一半以上的时间,因此即使完全优化循环,总执行时间也只会减少一半。不过很有趣的问题。 -
我没有看到样本中应该有(或至少)一些给定数量的点的任何约束,所以:为什么不随机选择任何一个点,并称之为你的样本? (解读为:考虑一个适当的约束或惩罚函数,并将其添加到您的问题中。)
-
@zelanix 高度依赖
d0的值。较小的d0s 会使循环变慢。 -
我的意思是,没有什么能阻止“选择一个点”成为您问题的有效答案正如目前所说的。由于这可能不是对您有用的答案,因此您需要通过添加一些禁止将其作为答案的约束来更新您的问题。
-
@j_random_hacker 感谢您的通知,我编辑了问题。