Accord KDTree具有自定义距离函数

时间:2016-05-05 17:48:40

标签: c# geo kdtree accord.net

我有一个表示道路网络的图形数据结构(节点是道路中的点/交叉点,边缘是道路)。 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(即lat / lon数组的数组)以及相关节点,再加上我的自定义距离函数。看起来这个FromData构造函数实际上(出于某种原因?)调用我的ApproximateDistance函数,数组[1]和[1]作为两个输入参数,显然引发了一个异常,因为这个方法需要两个二维数组。

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

2 个答案:

答案 0 :(得分:2)

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

相反,它是与分裂平面的一维偏差。这里它是 纬度经度。

这就是为什么k-d-tree除了Minkowski规范之外几乎不支持的原因。

答案 1 :(得分:1)

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

Inspecting the current code,在构造树之前,我无法看到代码是如何调用ApproximateDistance的,因为您可能会看到仅在该方法的最后设置。

如果您仍然遇到此问题,请在问题跟踪器中注册,并提供一个触发问题的小示例,以便最终修复。

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

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