An open API service indexing awesome lists of open source software.

https://github.com/zabuzard/closy

Closy is a library that provides fast and generic solutions for nearest neighbor search (NNS)
https://github.com/zabuzard/closy

api knearest-neighbor-algorithm library nearest-neighbor-search nearest-neighbors nns nnsearch

Last synced: 7 months ago
JSON representation

Closy is a library that provides fast and generic solutions for nearest neighbor search (NNS)

Awesome Lists containing this project

README

          

# Closy
[![codefactor](https://img.shields.io/codefactor/grade/github/Zabuzard/Closy)](https://www.codefactor.io/repository/github/zabuzard/closy)
[![maven-central](https://img.shields.io/maven-central/v/io.github.zabuzard.closy/closy)](https://search.maven.org/search?q=g:io.github.zabuzard.closy)
[![javadoc](https://javadoc.io/badge2/io.github.zabuzard.closy/closy/javadoc.svg?style=flat&color=AA82FF)](https://javadoc.io/doc/io.github.zabuzard.closy/closy)
![Java](https://img.shields.io/badge/Java-9%2B-ff696c)
[![license](https://img.shields.io/github/license/Zabuzard/Closy)](https://github.com/Zabuzard/Closy/blob/master/LICENSE)

Closy is a simple library for efficient **nearest neighbor computations**. It is designed generic and can be used
with **any class** that defines a [metric](https://en.wikipedia.org/wiki/Metric_(mathematics)).

It is able to compute the nearest neighbor to a given point, as well as retrieving the k-nearest neighbors and also all
neighbors within a given range. The corresponding methods are:

* `Optional getNearestNeighbor(E point)`
* `Collection getKNearestNeighbors(E point, int k)`
* `Collection getNeighborhood(E point, double range)`

# Requirements

* Requires at least **Java 9**

# Download

Maven:

```xml

io.github.zabuzard.closy
closy
1.2.1

```

Jar downloads are available from the [release section](https://github.com/ZabuzaW/Closy/releases).

# Documentation

* [API Javadoc](https://javadoc.io/doc/io.github.zabuzard.closy/closy) or alternatively from the [release section](https://github.com/ZabuzaW/Closy/releases)

# Getting started

1. Integrate **Closy** into your project. The API is contained in the module `io.github.zabuzard.closy`.
2. Create an implementation of `Metric` for your custom `E` objects
3. Create an algorithm using `NearestNeighborComputations#of(Metric)`
4. Add your objects to the algorithm using `NearestNeighborComputation#add(E)`
5. Execute nearest neighbor computations using the methods offered by `NearestNeighborComputation`

# Example

Consider the following simple class for points in a 2-dimensional space

```java
class Point {
private final int x;
private final int y;

// constructor, getter, equals, hashCode and toString omitted
}
```

As first step, we need to define a `Metric` that operates on `Point`. We decide for
the [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance):

```java
class EuclideanDistance implements Metric {
@Override
public double distance(final Point a, final Point b) {
return Math.sqrt(Math.pow(b.getX() - a.getX(), 2) + Math.pow(b.getY() - a.getY(), 2));
}
}
```

Next, we create an algorithm using this metric and then add some points to it:

```java
var metric = new EuclideanDistance();
var algo = NearestNeighborComputations.of(metric);

algo.add(Point.of(1, 2));
algo.add(Point.of(5, 7));
algo.add(Point.of(-10, 4));
algo.add(Point.of(9, 8));
algo.add(Point.of(3, 3));
```

Finally, we use the methods provided by `NearestNeighborComputation`
to compute some nearest neighbors:

```java
var point = Point.of(4, 2);
Optional neighbor = algo.getNearestNeighbor(point); // (3, 3)
Collection neighbors = algo.getKNearestNeighbors(point, 3); // [(3, 3), (1, 2), (5, 7)]
Collection neighborhood = algo.getNeighborhood(point, 3.5); // [(1, 2), (3, 3)]
```

***

# Background

The current implementation uses [Cover Trees](https://en.wikipedia.org/wiki/Cover_tree), based on the implementation
described in [Cover Trees for Nearest Neighbor](https://dl.acm.org/citation.cfm?id=1143857) (_Beygelzimer et al. in
ICML '06_).

A detailed description and benchmark can be found
in [Multi-Modal Route Planning in Road and Transit Networks](https://arxiv.org/abs/1809.05481) (_Daniel Tischner '18_).

The following is a benchmark of [Closy version 1.0](https://github.com/Zabuzard/Cobweb). The experiment consists of
continuous insertion of nodes, for each of three road networks respectively, and then measuring random nearest neighbor
queries, i.e. the execution time of the algorithm. Measurements are done for tree sizes of 1, 10000 and then in steps of

10000. Each measurement is averaged over 1000 queries using randomly selected nodes.

![Close version 1.0 benchmark](https://i.imgur.com/8qWYBG7.png)