【问题标题】:How do you build a KDTree in Java如何在 Java 中构建 KDTree
【发布时间】:2020-03-09 18:33:49
【问题描述】:

我查看了几个实现,它们有点令人困惑,我希望能对从点列表构建 KDTree 所需的内容进行某种细分。我最终将使用这个 KDTree 来执行 2D K-nearest-neighbors 搜索。

这是我目前所拥有的,数量不多。

点类

   class Point{
   public PVector p;

   public Point(float x, float y){
     p = new PVector(x,y);
   }

   public Point(PVector _p0 ){
     p = _p0;
   }

   float getX(){ return p.x; }
   float getY(){ return p.y; }

   float x(){ return p.x; }
   float y(){ return p.y; }

   public float distance( Point o ){
     return PVector.dist( p, o.p );
   }

节点类

class Node{
  Node left;
  Node right;
  Point p;

  Node(Point _p, Node l, Node r){
    p = _p;
    left = l;
    right = r;
  }
}

KDTree 类

class KDTree{
  Node root;

  KDTree()
  {
    root = null;
  }

}

正如您所见,Node 和 KDTree 类并没有真正实现,这就是我遇到的问题。

我想最终构建这个 KDTree,方法是:ArrayList points

任何帮助将不胜感激!

【问题讨论】:

  • 欢迎来到 SO。您的问题读作请求某人为您编写 KDTree 实现。我可以建议您阅读en.wikipedia.org/wiki/K-d_tree 平衡树的标准算法的描述并尝试自己实现它吗?这个论坛最适合回答您遇到的特定技术问题,而不是一般的“我如何实现 X?”
  • 是的,我已经阅读了 wiki。我并不是真的要求有人为我编写代码,所以我问的是我的 Node 类看起来是否准确,以及我需要为 KDTree 类实现什么样的功能。
  • 好的,我可以在答案中对这些事情给出一些指示。

标签: java nearest-neighbor kdtree


【解决方案1】:

关于你的代码结构和你需要实现的方法,我建议它应该如下所示:

enum Axis {
    X, Y;

    public Axis next() {
        return values()[(ordinal() + 1) % values().length];
    }
}

interface Node {
    Point closestTo(Point point);
}

class Leaf implements Node {
    private final Point point;

    public Leaf(Point point) {
        this.point = point;
    }

    public Point closestTo(Point point) {
        return this.point;
    }
}

class Branch implements Node {
    private final Axis axis;
    private final Point median;
    private final Node smaller;
    private final Node larger;

    public Branch(Axis axis, Point median, Node smaller, Node larger) {
        this.axis = axis;
        this.median = median;
        this.smaller = smaller;
        this.larger = larger;
    }

    public Point closestTo(Point point) {
        ...
    }
}

class KD_Tree {
    private final Optional<Node> root;

    public KD_Tree(List<Point> points) {
        this.root = makeNode(points);
    }

    private Optional<Node> makeNode(Axis axis, List<Point> points) {
        switch (points.size()) {
            case 0: 
                return Optional.empty();
            case 1: 
                return Optional.of(new Leaf(points.get(0));
            default:
                Point median = medianOf(points);
                Node smaller = makeNode(axis.next(), lessThan(median, points)).get();
                Node larger = makeNode(axis.next(), greaterThan(median, points)).get();
                return Optional.of(new Branch(axis, median, smaller, larger));
        }
    }
}

还有很多逻辑要写在那里,但希望这能让你开始。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 2020-02-11
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多