我正在寻找以下问题的快速解决方案:
我有一个固定点(比如说白色测量线的右上角),需要找到由等间距点(下面的曲线)构成的曲线上的最近点。另外,我对上曲线上的每个点执行此操作,以绘制具有不同颜色的曲线之间的距离(三个级别:低于最小值[红色],最小值和最大值[橙色]之间以及高于最大值[绿色])。
我目前的解决方案是权衡:我采用固定点,迭代任意间隔(例如固定点左侧和右侧50个单位)并计算每对的距离。这节省了一些CPU功率,但它既不优雅也不准确,因为我可能会错过我选择的间隔之外的最小距离。
有关更快算法的任何建议吗?
编辑:等间距意味着所有点在x轴上具有相同的距离,这对于两条曲线都是如此。此外,我不需要在点之间进行插值,这将非常耗时。
答案 0 :(得分:3)
而不是任意距离,你可以迭代直到“超出范围”。
在您的示例中,假设您从行右上角的上部曲线上的点开始。然后垂直向下,你(我的眼睛)的距离约为200um。
现在您可以从此处测试点向右移动,直到水平距离为200um。除此之外,距离不到200um是不可能的。
向左移动,距离下降,直到找到150um最小值,然后再次开始上升。一旦你在你的高点左侧150um,再次,你不可能击败你找到的最低点。
如果你先离开,你就不必走得那么远,所以优化要么遵循距离下降的方向,要么一次从中间向两个方向进行。
我不知道有多少是50个单位,所以这可能比你的速度慢或快。但它确实避免了错过较低值的风险。
由于您正在对下曲线上的同一组点进行大量测试,因此可以通过忽略这些点形成曲线的事实来合理地改进。将它们全部粘贴在k-d树或类似物中,并反复搜索。它被称为Nearest neighbor search。
答案 1 :(得分:3)
将此问题识别为nearest neighbour search问题可能会有所帮助。该链接包括对用于此的各种算法的良好讨论。如果您可以使用C ++而不是直接使用C语言,ANN看起来就像是一个很好的库。
看起来好像这个问题是asked before。
答案 2 :(得分:2)
我们可以标出顶部曲线y = t(x)和底部曲线y = b(x)。标记最近函数x_b = c(x_t)。我们知道最近函数是弱单调不递减的,因为两条最短路径永远不会相互交叉。
如果您知道距离函数d(x_t,x_b)对于每个固定的x_t只有一个局部最小值(如果曲线“足够平滑”,则会发生这种情况),那么您可以通过“行走”曲线来节省时间:
- start with x_t=0, x_b=0
- while x_t <= x_max
-- find the closest x_b by local search
(increment x_b while the distance is decreasing)
-- add {x_t, x_b} to the result set
-- increment x_t
如果你期望x_b足够平滑,但是你不能假设它并且你想要一个确切的结果,
沿两个方向走弯道。如果结果一致,它们是正确的。在他们不同意的地方,在两个结果(最左边和最右边的局部最大值)之间进行完整搜索。以这样的顺序(二元除法)对“模糊块”进行采样,以便由于单调性而进行最多的修剪。
作为中间立场:
沿两个方向走弯道。如果结果不一致,请从两者中选择。如果每个固定的x_t最多可以保证两个局部最大值,则可以得到最优解。仍然存在一些病理情况,其中没有找到最优解,并且包含局部最小值,其侧翼是两个比这个更差的局部最小值。我敢说,找到一个解决方案远非最优的情况并不常见(假设平滑y = b(x))。