【问题标题】:How to speed up this object comparison algorithm? [duplicate]如何加快这个对象比较算法? [复制]
【发布时间】:2013-09-04 12:04:46
【问题描述】:

考虑一个维度为Nx2 的矩阵,其中每一行包含一个统一PDF(即概率密度函数)的下限和上限。

我想统计重叠的数量,其中重叠定义为两个PDF重叠的情况,例如:

  • PDF1:[2,5]
  • PDF2:[3,6]
  • 两个 PDF 在区间 [3,5] 内重叠。

显然,如果三个 PDF 文件 p1p2p3 重叠,我计算三个重叠:p1 vs. p2p1 vs.p3p2 vs. p3.

我创建了以下计算重叠的 MATLAB 代码:

for m = 1:N-1
    for k = m+1:N
        l1 = dataService.getObjectCoordinate(m,1);
        l2 = dataService.getObjectCoordinate(k,1);
        u1 = dataService.getObjectCoordinate(m,2);
        u2 = dataService.getObjectCoordinate(k,2);
        if (l1 <= l2 && l2 <= u1) || (l2 <= l1 && l1 <= u2)
            numOverlaps = numOverlaps + 1;
        end
    end
end 

但是,您可以想象,这是 O(N^2),当 N 很大时,这非常糟糕。我在三个小时前使用N=10000 开始执行,它仍在运行。

您能否提出一种降低所提出算法复杂性的方法,或许可以排除一些先验比较?

提前致谢。

【问题讨论】:

  • @MZimmerman6:我链接到的问题至少有一个答案在 O(N·logN) 内完成。
  • @RodyOldenhuis 是的,我刚刚看过,我正在编写代码以减少...我想。我们将看看这是怎么回事。到目前为止,我所拥有的是不到一秒钟的时间

标签: performance matlab comparison complexity-theory


【解决方案1】:

我收回我之前留下的评论。你绝对可以在更短的时间内做到这一点。根据 Rody 和 Shoelzer 提供的链接,您可以使用以下代码在一秒钟内完成此操作

tic
numIntervals = 10000;
ranges = sort(randi(100,[numIntervals,2]),2);
[vals,idx] = sort(ranges(:,1));
ranges = ranges(idx,:);
overlaps = false(numIntervals);
for i = 1:numIntervals
    temp = [ranges(:,1) <= ranges(i,2),ranges(:,1) >= ranges(i,1)];
    overlaps(:,i) = logical(all(temp,2));
end
overlaps = tril(overlaps,-1);
toc

ranges 将是您的区间起点和终点的数组。

末尾的下三角形部分的目的是删除任何重复的对。如果P1P2 重叠,那么显然P2 将与P1 重叠。它还将通过删除对角线消除P1 与自身重叠的事实

运行大量数据时请务必小心,因为它使用的存储量会很快填满您的 RAM,具体取决于您拥有的数量。我尝试将所有内容都保留为逻辑数组以帮助解决此问题,但它仍然会快速增加。

您绝对可以删除存储部分并为自己节省大量时间,但是您必须在每个循环中立即处理所有事情。

【讨论】:

  • 如果我错了,请纠正我,但我认为这只是 O(N²)——在每次迭代中,你都会进行 3N 次比较(不要忘记all()),然后循环 N次。它跑得快并不是因为算法快,而是因为 10000 并不是一个很大的数字。
  • 它可能仍然是 O(n^2) 它只是使用了 MATLAB 中逻辑运算符的强大功能。
  • 我意识到这一点,但请记住 big-O 指的是 算法 复杂性;隐含地假设使用了该语言中可能的最佳实现。因此,使用具有 O(N·logN) 算法的 MATLAB 运算符 的强大功能,可以使执行时间像您发现的那样对于更大的 N 也是可能的——您的 O(N²) 会更快地发散,因为N 增长。
  • 当然,我明白这个事实。我不一定要说明它的复杂性。但就发帖人的要求而言,对于 10000 个间隔,此代码不会像当前实现那样花费数小时。
  • 是的。我只是对这个问题产生了学术兴趣:)
【解决方案2】:

您是否分析过您的代码?问题的很大一部分可能是您每次迭代调用dataService.getObjectCoordinate() 四次。相反,尝试一次获取所有数据并将其存储在数组中,然后再进行任何比较。

之后,使用Possible Interview Question: How to Find All Overlapping Intervals 的答案中描述的技术。

【讨论】:

    猜你喜欢
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    • 2014-01-12
    • 1970-01-01
    • 2019-05-19
    • 1970-01-01
    相关资源
    最近更新 更多