如何用Java构建KDTree

如何用Java构建KDTree,java,nearest-neighbor,kdtree,Java,Nearest Neighbor,Kdtree,我已经看过了一些实现,它们有点让人困惑,我希望能从一系列点中分解出构建KDTree所需的内容。我将使用这个KDTree来执行2D K近邻搜索 这是我到目前为止所拥有的,并不多 点类 class Point{ public PVector p; public Point(float x, float y){ p = new PVector(x,y); } public Point(PVector _p0 ){ p = _p0; }

我已经看过了一些实现,它们有点让人困惑,我希望能从一系列点中分解出构建KDTree所需的内容。我将使用这个KDTree来执行2D K近邻搜索

这是我到目前为止所拥有的,并不多

点类

   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:ArrayListpoints


任何帮助都将不胜感激

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

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));
        }
    }
}
enum轴{
十、 Y;
公共轴下一个(){
返回值()[(序号()+1)%values().length];
}
}
接口节点{
接近点(点-点);
}
类叶实现节点{
私人终点;
公共叶(点){
这个点=点;
}
公共点靠近(点){
返回此点;
}
}
类分支实现节点{
私人终轴;
私人终点中位数;
私有最终节点较小;
私有最终节点较大;
公共分支(轴线、点中线、节点较小、节点较大){
这个轴=轴;
这个中位数=中位数;
这个。更小=更小;
这个。更大=更大;
}
公共点靠近(点){
...
}
}
类KD_树{
私有最终可选根;
公共KD_树(列表点){
this.root=生成节点(点);
}
专用可选makeNode(轴、列表点){
开关(points.size()){
案例0:
返回可选的.empty();
案例1:
返回可选的.of(新叶(points.get(0));
违约:
点中值=中间值(点);
节点较小=makeNode(axis.next(),lessThan(median,points)).get();
大于节点=生成节点(axis.next(),大于(中值,点)).get();
返回可选的.of(新分支(轴、中位数、较小、较大));
}
}
}

还有很多逻辑需要编写,但希望能让您开始。

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

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));
        }
    }
}
enum轴{
十、 Y;
公共轴下一个(){
返回值()[(序号()+1)%values().length];
}
}
接口节点{
接近点(点-点);
}
类叶实现节点{
私人终点;
公共叶(点){
这个点=点;
}
公共点靠近(点){
返回此点;
}
}
类分支实现节点{
私人终轴;
私人终点中位数;
私有最终节点较小;
私有最终节点较大;
公共分支(轴线、点中线、节点较小、节点较大){
这个轴=轴;
这个中位数=中位数;
这个。更小=更小;
这个。更大=更大;
}
公共点靠近(点){
...
}
}
类KD_树{
私有最终可选根;
公共KD_树(列表点){
this.root=生成节点(点);
}
专用可选makeNode(轴、列表点){
开关(points.size()){
案例0:
返回可选的.empty();
案例1:
返回可选的.of(新叶(points.get(0));
违约:
点中值=中间值(点);
节点较小=makeNode(axis.next(),lessThan(median,points)).get();
大于节点=生成节点(axis.next(),大于(中值,点)).get();
返回可选的.of(新分支(轴、中位数、较小、较大));
}
}
}

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

欢迎这么做。你的问题是要求有人为你编写KDTree实现。我建议你阅读关于平衡树的标准算法的描述,并尝试自己实现它。这个论坛最适合你回答您遇到的特定技术问题,而不是一般的“我如何实现X?”是的,我已经阅读了wiki。我并不是真的要求有人为我编写代码,更重要的是,我要问的是,我的节点类看起来是否准确,以及我需要为KDTree类实现什么样的函数。好的,我可以在nswer。欢迎访问SO。您的问题读作是请求某人为您编写KDTree实现。我建议您阅读关于平衡树的标准算法的描述,并尝试自己实现它。此论坛最适合回答您遇到的特定技术问题,而不是一般的“我如何实现?”“是的,我读过维基。我不是真的要求有人帮我把它编码出来,更重要的是,我要问的是我的节点类看起来是否准确,以及我需要为KDTree类实现什么样的函数。好的,我可以在回答中给出一些关于这些事情的指针。