【问题标题】:Accord KDTree with custom distance functionAccord KDTree 与自定义距离函数
【发布时间】:2016-08-31 14:58:36
【问题描述】:

我有一个表示道路网络的图形数据结构(节点是道路中的点/交叉点,边是道路)。 Node 对象具有与之关联的纬度和经度。

我正在使用 Accord 的 KDTree 类来查找给定 GPS 坐标附近的节点。由于 Accord 似乎没有将 Haversine 距离作为内置距离函数(我错了吗?),我定义了自己的自定义距离函数,并将其作为额外参数传递给 KDTree.FromData() 方法,如下:

        var nodes = graph.Nodes;
        //Initialize KD-tree with distance function defined as the cartesian approximate distance (in meters) 
        Func<double[], double[], double> distanceFunc = (x, y) => DistanceFunctions.ApproximateDistance(x,y);
        kdTreeOfNodes = KDTree.FromData<Node>(nodes.Select(x => new double[] { x.Value.Latitude, x.Value.Longitude }).ToArray(), nodes.ToArray(), distanceFunc);

请注意,“ApproximateDistance”被定义为单独类中的静态方法,并且是更正确的Haversine 距离的笛卡尔近似值。

尝试执行最后一行时出现异常。在这一行中,我传入要放入 KDTree(即纬度/经度数组)以及相关节点的数据以及我的自定义距离函数。似乎这个 FromData 构造函数实际上(出于某种原因?)调用了我的 ApproximateDistance 函数,其中数组 [1] 和 [1] 作为两个输入参数,显然引发了异常,因为此方法需要两个二维数组。

我不知道为什么这个构造函数会调用我的 ApproximateDistance 函数(尤其是使用这些奇怪的参数),并且似乎无法使用调试器找出...

【问题讨论】:

  • 你得到了什么异常?
  • 索引超出范围异常(ApproximateDistance函数需要二维数组,传入一维数组)。

标签: c# geo kdtree accord.net


【解决方案1】:

K-d-tree 在搜索过程中不使用点对点距离,直到它们到达实际数据点。

相反,它是一个一维的偏差,从分裂平面。此处将是任一纬度经度。

这就是 k-d-tree 仅支持 Minkowski 范数的原因。

【讨论】:

  • 对。所以你是说我应该有一个一维距离函数?这对于纬度/经度来说将是有问题的,因为它们在技术上需要单独的距离函数(并且纵向距离将取决于“参考纬度” - 如果我们知道我们所在的纬度,我们只能知道与经度变化相关的距离) ...无论如何,为什么这个 KDTree 构造函数实际上调用了这个方法?当然,只有在我尝试使用该类时才会出现异常?
  • 是的。除非您可以将距离分解为一维函数,否则我认为这行不通。
  • 我不买那个...然后我又没有正确理解 KD 树的工作原理。但是 Accord 有多个可以指定的距离函数,包括例如欧式距离(本质上是多维距离,不能用一维距离函数代替……)
  • 另外,另一个问题仍然存在 - 为什么 FromData 构造函数调用距离方法?它是输入自己的“测试”值还是使用输入数据?
  • 此外,关于多维距离:FromData 方法的最后一个参数是 Func 类型的函数对象,清楚地表明它期望多维距离函数(否则它只需要一个 Func 类型的函数)。
【解决方案2】:

Accord.NET 中的 K-d 树不应该调用您的 Distance 函数,除非您在树中执行查找(即通过调用任何 .NearestApproximateNearest 函数)。正如 Anony-Mousse 正确指出的那样,K-d 树在到达实际数据点之前不使用点对点距离,即当您执行搜索时。

Inspecting the current code,在构造树之前,我看不出代码是如何调用 ApproximateDistance 的,正如您可能看到的那样,它只设置在该方法的最后。

如果您仍然遇到此问题,请将其注册到问题跟踪器中,并附上一个触发问题的小示例,以便最终解决。

另外,如果您需要其他依赖点到点距离的树,您可能还想看看最近添加的Vantage-Point Trees

免责声明:我是 Accord.NET 中 k-d 树实现的作者。

【讨论】:

  • 感谢您的回复!事实上,我在图中寻找附近的边,所以寻找附近的节点被证明是错误的方法,我最终实现了我自己的基于网格的搜索,效果很好。无论如何,被调用的距离方法很奇怪,但我现在不能再复制这个问题了。附言Vantage-Point Trees 听起来棒极了!
猜你喜欢
  • 2021-06-21
  • 2016-02-17
  • 1970-01-01
  • 2018-07-14
  • 2020-02-25
  • 1970-01-01
  • 2020-02-09
  • 2016-02-19
相关资源
最近更新 更多