ANN(Approximate Nearest Neighbor) 库的安装
1、ANN介绍
ANN 是一个用 C++ 编写的库,它支持任意高维度的精确和近似最近邻搜索的数据结构和算法 。
-
在最近邻问题中,给出了 d 维空间中的一组数据点。这些点被预处理成数据结构,以便给定任何查询点q,可以有效地查找P到q的最近的或一般k个最近的点。两点之间的距离可以通过多种方式定义。 ANN 假设距离是使用任何一类称为
Minkowski
度量的距离函数来测量的。其中包括众所周知的欧几里得距离、曼哈顿距离和最大距离。 -
该库基于
kd
树和框分解树实现了许多不同的数据结构,并采用了几种不同的搜索策略。 -
该库还附带了用于测量 ANN 在任何特定数据集上的性能质量的测试程序,以及用于可视化几何数据结构的程序。
2、下载
下载Release版本的需要自己在VS中编译。编译需要特定的工具支撑,容易出错。建议下载含有头文件和dll
和lib
文件的版本,解压后便可直接使用。解压后如下:
3、安装
我下载了ANN的需要编译的版本,将lib
拷贝到了对应的lib文件夹下**
在系统变量的Path中也添加了该bin文件(不知道是否真的需要)
#include <ANN.h> // 包含 ANN 库头文件
#include <iostream>
#include <random> // 用于生成随机数
#include <fstream> // 用于文件操作
#include <chrono>
int main() {
const int nPoints = 2700; // 数据点数量
const int dim = 1; // 数据的维度(一维)
const int k = 300; // 需要查找的最近邻数量
// 创建数据点数组
ANNpointArray dataPts = annAllocPts(nPoints, dim);
// 使用随机数生成器生成随机数据点
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(0.0, 1.0);
for (int i = 0; i < nPoints; ++i) {
dataPts[i][0] = dis(gen); // 生成 [0.0, 1.0) 区间的随机浮点数
}
// 存储最近邻结果
ANNidxArray nnIdx = new ANNidx[k]; // 最近邻的索引
ANNdistArray dists = new ANNdist[k]; // 最近邻的距离
// 构建 KD-Tree
ANNkd_tree* kdTree = new ANNkd_tree(dataPts, nPoints, dim);
// 打开文件以写入
std::ofstream outputFile("results.txt");
// 查询每个点的 300 个最近邻点并将结果写入文件
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < nPoints; ++i) {
kdTree->annkSearch(dataPts[i], k, nnIdx, dists, 0.0);
// 输出当前点的最近邻结果到文件
outputFile << "Point " << i << " (Value: " << dataPts[i][0] << ") Nearest neighbors:\n";
for (int j = 0; j < k; ++j) {
outputFile << "\tNeighbor " << j << ": Index: " << nnIdx[j]
<< ", Value: " << dataPts[nnIdx[j]][0]
<< ", Distance: " << sqrt(dists[j]) << "\n";
}
outputFile << "\n";
}
auto end = std::chrono::steady_clock::now();
// 计算持续时间(以毫秒为单位)
std::chrono::duration<double, std::milli> duration = end - start;
std::cout << "Duration: " << duration.count() << " ms" << std::endl;
// 关闭文件
outputFile.close();
// 释放内存
delete[] nnIdx;
delete[] dists;
delete kdTree;
annDeallocPts(dataPts);
annClose(); // 释放 ANN 内存
return 0;
}
补充:
- ANN库原始工程使用32位编译,对于工程中的64位库并不适用
- 可以将src文件夹中的源码添加到现有工程中,编译即可
- 如果是C和C++混编的工程,要将调用该库的文件使用cpp命名