我已经实现dbscan算法来对3d点云数据进行聚类。它确实工作得很好,但是唯一的问题是处理时间太长。 6000点云将近15秒。要实现多线程以减少处理时间。如果可以帮助在以下完整的代码段上实现多线程,将不胜感激。谢谢!
public ArrayList<List<Vector>> Run() {
int index = 0; //index for each point cloud (cloud -->input data)
List <Vector> neighbors;
ArrayList<List<Vector>> resultList = new ArrayList<List<Vector>>(); //group of cluster --> ArrayList<list<Vector>>
while (cloud.size() > index) {
Vector p = cloud.get(index);
if (!visited.contains(p)) {
visited.add(p);
neighbors = get_neighbors(p);
if (neighbors.size() >= minPts) { //minpts = 5
int ind = 0;
while (neighbors.size() > ind) {
Vector r = neighbors.get(ind);
if (!visited.contains(r)) {
visited.add(r);
List<Vector> individualNeighbors = get_neighbors(r);
if (individualNeighbors.size() >= minPts) {
neighbors = merge_neighbors(
neighbors,
individualNeighbors);
}
}
ind++;
}
resultList.add(neighbors);
}
}
index++;
}
return resultList;
}
private List<Vector> merge_neighbors(List<Vector>neighborPts1, List<Vector>neighborPts2) {
for (Vector n2: neighborPts2) {
if (!neighborPts1.contains(n2)) {
neighborPts1.add(n2);
}
}
return neighborPts1;
}
private List<Vector> get_neighbors(Vector pt){
CopyOnWriteArrayList<Vector> pts = new CopyOnWriteArrayList<>();
for (Vector p: cloud) {
if (computeDistance (pt,p)<=eps*eps) {
pts.add(p);
}
}
return pts;
}
private double computeDistance (Vector core,Vector target) {
return Math.pow(core.getX()-target.getX(),2)
+ Math.pow(core.getY()-target.getY(),2)
+Math.pow(core.getZ()-target.getZ(),2);
}
}
答案 0 :(得分:0)
A)您的实现中有很多优化潜力,比多线程更容易实现。因此,首先优化您的代码。
特别是,如果将数据加载到ELKI之类的工具中(请确保添加空间索引,这不是默认值),您会注意到它们即使仅使用一个线程也可以运行得更快
B)在多核DBSCAN上有一些出版物,讨论了压制DBSCAN时的困难和挑战。首先阅读,因为对于此问答格式而言,整个故事已久了:
Patwary,M.A.,Palsetia,D.,Agrawal,A.,Liao,W.K.,Manne,F.&Choudhary,A.(2012年11月)。使用不交集数据结构的新的可伸缩并行DBSCAN算法。在高性能计算,网络,存储和分析国际会议论文集(第62页)中。 IEEE计算机协会出版社。
Götz,M.,Bodenstein,C.,&Riedel,M.(2015年11月)。 HPDBSCAN:高度并行的DBSCAN。在高性能计算环境中机器学习研讨会的论文集(p.2)中。 ACM。
Welton,B.,Samanas,E.,&Miller,B.P.(2013年11月)。 Mr. scan:使用基于树的gpgpu节点网络,基于极限规模密度的群集。在SC'13中:高性能计算,网络,存储和分析国际会议论文集(第1-11页)。 IEEE。