dbscan java_DBSCAN算法的Java,C++,Python实现

最近由于要实现‘基于网格的DBSCAN算法’,网上有没有找到现成的代码[如果您有代码,麻烦联系我],只好参考已有的DBSCAN算法的实现。先从网上随便找了几篇放这儿,之后对比研究。

DBSCAN简介:

1.简介

DBSCAN 算法是一种基于密度的空间聚类算法。该算法利用基于密度的聚类的概念,即要求聚类空间中的一定区域内所包含对象(点或其它空间对象)的数目不小于某一给定阀   值。DBSCAN 算法的显著优点是聚类速度快且能够有效处理噪声点和发现任意形状的空间聚类。但是由于它直接对整个数据库进行操作且进行聚类时使用了一个全局性的表征  密度的参数,因此也具有两个比较明显的弱点:

1. 当数据量增大时,要求较大的内存支持 I/0 消耗也很大;

2. 当空间聚类的密度不均匀、聚类间距离相差很大时,聚类质量较差。

2.DBSCAN算法的聚类过程

DBSCAN算法基于一个事实:一个聚类可以由其中的任何核心对象唯一确定。等价可以表述为: 任一满足核心对象条件的数据对象p,数据库D中所有从p密度可达的数据对象o  所组成的集合构成了一个完整的聚类C,且p属于C。

3.DBSCAN中的几个定义

密度可达是直接密度可达的传递闭包,非对称性关系;密度相连是对称性关系。DBSCA目的是找到密度相连对象的最大集合。

E领域:给定对象p半径为E内的区域称为该对象的E领域;

核心对象:p的E领域内样本数大于MinPts(算法输入值),则该对象p为核心对象;

直接密度可达:对于样本集合D,如果样本点q在p的E领域内,且p为核心对象,则p直接密度可达q;

密度可达:对于样本集合D,存在一串样本点p1,p2,p3,...pn,其中连续两个点直接密度可达,则 p=p1,q=qn,则p密度可达q;

密度相连:对于样本集合D中任意一点o,存在p到o密度可达,并且q到o密度可达,那么q从p密度相连;

算法伪代码

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 DBSCAN(SetOfPoints, Eps, MinPts){2 ClusterId=nextId(NOISE)3 for(i=0;i

13 ExpandCluster(SetOfPoints,Point, ClId, Eps, MinPts){14 seeds=SetOfPoints.regionQuery(Point, Eps)15 if(seeds.size()0){22 currentP=seeds.first()23 result=SetOfPoints.regionQuery(currentP, Eps)24 if(result.size()>=MinPts){25 for(i=0;i

View Code

JAVA实现:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packageorisun;2

3 importjava.io.File;4 importjava.util.ArrayList;5 importjava.util.Vector;6 importjava.util.Iterator;7

8 public classDBScan {9

10 double Eps=3; //区域半径

11 int MinPts=4; //密度12

13 //由于自己到自己的距离是0,所以自己也是自己的neighbor

14 public Vector getNeighbors(DataObject p,ArrayListobjects){15 Vector neighbors=new Vector();16 Iterator iter=objects.iterator();17 while(iter.hasNext()){18 DataObject q=iter.next();19 double[] arr1=p.getVector();20 double[] arr2=q.getVector();21 int len=arr1.length;22

23 if(Global.calEditDist(arr1,arr2,len)<=Eps){ //使用编辑距离24 //if(Global.calEuraDist(arr1, arr2, len)<=Eps){//使用欧氏距离25 //if(Global.calCityBlockDist(arr1, arr2, len)<=Eps){//使用街区距离26 //if(Global.calSinDist(arr1, arr2, len)<=Eps){//使用向量夹角的正弦

27 neighbors.add(q);28 }29 }30 returnneighbors;31 }32

33 public int dbscan(ArrayListobjects){34 int clusterID=0;35 boolean AllVisited=false;36 while(!AllVisited){37 Iterator iter=objects.iterator();38 while(iter.hasNext()){39 DataObject p=iter.next();40 if(p.isVisited())41 continue;42 AllVisited=false;43 p.setVisited(true); //设为visited后就已经确定了它是核心点还是边界点

44 Vector neighbors=getNeighbors(p,objects);45 if(neighbors.size()

48 }else{49 if(p.getCid()<=0){50 clusterID++;51 expandCluster(p,neighbors,clusterID,objects);52 }else{53 int iid=p.getCid();54 expandCluster(p,neighbors,iid,objects);55 }56 }57 AllVisited=true;58 }59 }60 returnclusterID;61 }62

63 private void expandCluster(DataObject p, Vectorneighbors,64 int clusterID,ArrayListobjects) {65 p.setCid(clusterID);66 Iterator iter=neighbors.iterator();67 while(iter.hasNext()){68 DataObject q=iter.next();69 if(!q.isVisited()){70 q.setVisited(true);71 Vector qneighbors=getNeighbors(q,objects);72 if(qneighbors.size()>=MinPts){73 Iterator it=qneighbors.iterator();74 while(it.hasNext()){75 DataObject no=it.next();76 if(no.getCid()<=0)77 no.setCid(clusterID);78 }79 }80 }81 if(q.getCid()<=0){ //q不是任何簇的成员

82 q.setCid(clusterID);83 }84 }85 }86

87 public static voidmain(String[] args){88 DataSource datasource=newDataSource();89 //Eps=3,MinPts=4

90 datasource.readMatrix(new File("/home/orisun/test/dot.mat"));91 datasource.readRLabel(new File("/home/orisun/test/dot.rlabel"));92 //Eps=2.5,MinPts=493 //datasource.readMatrix(new File("/home/orisun/text.normalized.mat"));94 //datasource.readRLabel(new File("/home/orisun/text.rlabel"));

95 DBScan ds=newDBScan();96 int clunum=ds.dbscan(datasource.objects);97 datasource.printResult(datasource.objects,clunum);98 }99 }

View Code

C++实现:

数据结构

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include

2

3 using namespacestd;4

5 const int DIME_NUM=2; //数据维度为2,全局常量6

7 //数据点类型

8 classDataPoint9 {10 private:11 unsigned long dpID; //数据点ID

12 double dimension[DIME_NUM]; //维度数据

13 long clusterId; //所属聚类ID

14 bool isKey; //是否核心对象

15 bool visited; //是否已访问

16 vector arrivalPoints; //领域数据点id列表

17 public:18 DataPoint(); //默认构造函数

19 DataPoint(unsigned long dpID,double* dimension , bool isKey); //构造函数

20

21 unsigned long GetDpId(); //GetDpId方法

22 void SetDpId(unsigned long dpID); //SetDpId方法

23 double* GetDimension(); //GetDimension方法

24 void SetDimension(double* dimension); //SetDimension方法

25 bool IsKey(); //GetIsKey方法

26 void SetKey(bool isKey); //SetKey方法

27 bool isVisited(); //GetIsVisited方法

28 void SetVisited(bool visited); //SetIsVisited方法

29 long GetClusterId(); //GetClusterId方法

30 void SetClusterId(long classId); //SetClusterId方法

31 vector& GetArrivalPoints(); //GetArrivalPoints方法

32 };

View Code

实现

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include "DataPoint.h"

2

3 //默认构造函数

4 DataPoint::DataPoint()5 {6 }7

8 //构造函数

9 DataPoint::DataPoint(unsigned long dpID,double* dimension , boolisKey):isKey(isKey),dpID(dpID)10 {11 //传递每维的维度数据

12 for(int i=0; idimension[i]=dimension[i];15 }16 }17

18 //设置维度数据

19 void DataPoint::SetDimension(double*dimension)20 {21 for(int i=0; idimension[i]=dimension[i];24 }25 }26

27 //获取维度数据

28 double*DataPoint::GetDimension()29 {30 return this->dimension;31 }32

33 //获取是否为核心对象

34 boolDataPoint::IsKey()35 {36 return this->isKey;37 }38

39 //设置核心对象标志

40 void DataPoint::SetKey(boolisKey)41 {42 this->isKey =isKey;43 }44

45 //获取DpId方法

46 unsigned longDataPoint::GetDpId()47 {48 return this->dpID;49 }50

51 //设置DpId方法

52 void DataPoint::SetDpId(unsigned longdpID)53 {54 this->dpID =dpID;55 }56

57 //GetIsVisited方法

58 boolDataPoint::isVisited()59 {60 return this->visited;61 }62

63

64 //SetIsVisited方法

65 void DataPoint::SetVisited( boolvisited )66 {67 this->visited =visited;68 }69

70 //GetClusterId方法

71 longDataPoint::GetClusterId()72 {73 return this->clusterId;74 }75

76 //GetClusterId方法

77 void DataPoint::SetClusterId( longclusterId )78 {79 this->clusterId =clusterId;80 }81

82 //GetArrivalPoints方法

83 vector&DataPoint::GetArrivalPoints()84 {85 returnarrivalPoints;86 }

View Code

PYTHON实现:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 from matplotlib.pyplot import *

2 fromcollections import defaultdict3 import random4

5 #function to calculate distance6 def dist(p1, p2):7 return ((p1[0]-p2[0])**2+ (p1[1]-p2[1])**2)**(0.5)8

9 #randomly generate around 100cartesian coordinates10 all_points=[]11

12 for i in range(100):13 randCoord = [random.randint(1,50), random.randint(1,50)]14 if not randCoord inall_points:15 all_points.append(randCoord)16

17

18 #take radius = 8 and min. points = 8

19 E = 8

20 minPts = 8

21

22 #find outthe core points23 other_points =[]24 core_points=[]25 plotted_points=[]26 for point inall_points:27 point.append(0) # assign initial level 0

28 total = 0

29 for otherPoint inall_points:30 distance =dist(otherPoint,point)31 if distance<=E:32 total+=1

33

34 if total >minPts:35 core_points.append(point)36 plotted_points.append(point)37 else:38 other_points.append(point)39

40 #find border points41 border_points=[]42 for core incore_points:43 for other inother_points:44 if dist(core,other)<=E:45 border_points.append(other)46 plotted_points.append(other)47

48

49 #implement the algorithm50 cluster_label=0

51

52 for point incore_points:53 if point[2]==0:54 cluster_label+=1

55 point[2]=cluster_label56

57 for point2 inplotted_points:58 distance =dist(point2,point)59 if point2[2] ==0 and distance<=E:60 print point, point261 point2[2] =point[2]62

63

64 #after the points are asssigned correnponding labels, we group them65 cluster_list =defaultdict(lambda: [[],[]])66 for point inplotted_points:67 cluster_list[point[2]][0].append(point[0])68 cluster_list[point[2]][1].append(point[1])69

70 markers = ['+','*','.','d','^','v','>','

72 #plotting the clusters73 i=0

74 print cluster_list75 for value incluster_list:76 cluster=cluster_list[value]77 plot(cluster[0], cluster[1],markers[i])78 i = i%10+1

79

80 #plot the noise points aswell81 noise_points=[]82 for point inall_points:83 if not point in core_points and not point inborder_points:84 noise_points.append(point)85 noisex=[]86 noisey=[]87 for point innoise_points:88 noisex.append(point[0])89 noisey.append(point[1])90 plot(noisex, noisey, "x")91

92 title(str(len(cluster_list))+"clusters created with E ="+str(E)+"Min Points="+str(minPts)+"total points="+str(len(all_points))+"noise Points ="+str(len(noise_points)))93 axis((0,60,0,60))94 show()

View Code

参考:http://www.cnblogs.com/zhangchaoyang/articles/2182748.html

http://www.cnblogs.com/lovell-liu/archive/2011/11/08/2241542.html

http://blog.sudipk.com.np/2013/02/implementation-of-dbscan-algorithm-for.html

http://caoyaqiang.diandian.com/post/2012-09-26/40039517485

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/559399.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java volatile lock_Java并发学习笔记 -- Java中的Lock、volatile、同步关键字

Java并发一、锁1. 偏向锁1. 思想背景来源&#xff1a;HotSpot的作者经过研究发现&#xff0c;大多数情况下&#xff0c;锁不仅不存在多线程竞争&#xff0c;而且总是由同 一线程多次获得&#xff0c;为了让线程获得锁的代价更低而引入了偏向锁。原理&#xff1a;在对象头和栈帧…

python 数组赋值_pythonamp;numpy的赋值

有点编程基础的童鞋看到这个标题可能会有点懵逼&#xff0c;这还是个问题吗&#xff1f;不就是个等号()解决问题嘛&#xff01;我也希望是如此简单&#xff0c;因为上个星期被这个问题折磨到崩溃&#xff01;一般的python程序需要赋值时的确是通过等号()实现的&#xff0c;不管…

我的世界java 内存_我的世界如何分配内存

如果你在运行Minecraft时出现内存错误等问题&#xff0c;你可能需要给Minecraft分配更多内存来解决运行故障。如果你玩的是新版本的Minecraft&#xff0c;那么你可以从启动器里直接分配内存(RAM)。如果你使用的是旧版本&#xff0c;那么你需要创建一些文件来改变Minecraft内存使…

springbean的生命周期_spring bean生命周期(涵盖spring常用接口的载入)

spring bean生命周期流程图&#xff1a;​​​​其中包含了很多常用的接口&#xff0c;可以参考spring 常用接口&#xff1b;下面写个例子证明下&#xff1a;1.实现InitializingBean以及各个Aware接口public class UserB implements InitializingBean , BeanFactoryAware , Bea…

python中的索引从几开始计数_计算机为什么要从 0 开始计数?

作者&#xff1a;程序喵大人来源&#xff1a;程序喵大人大家好&#xff0c;我是猫哥&#xff01;众所周知&#xff0c;计算机是从0开始计数&#xff0c;而不是我们平时常用的从1开始计数&#xff0c;但你有想过为什么吗&#xff1f;其实不是计算机从0开始计数而是多数编程语言中…

coreos 安装mysql_如何执行CoreOS Linux的裸机安装

本文将介绍如何在裸机服务器上加载CoreOs Linux。关于在计算机上安装CoreOS Linux的更多方法。在本文中&#xff0c;我们将首先启动一些Live Linux发行版。从USB或CDROM提取Fedora&#xff0c;然后使用CoreOS的安装脚本在给定的硬盘驱动器上执行实际的CoreOS Linux。您将需要什…

websocket 发送图片_基于WebSocket的web端IM即时通讯应用的开发

基于WebSocket的web端IM即时通讯应用的开发功能列表&#xff1a;1、Web端的IM即时通讯应用2、支持上线、下线、实时在线提醒3、单聊、群聊的建立4、普通文字、表情、图片的传输(子定义富文本)5、单人的顶级提醒&#xff0c;多对话的窗口的提醒6、调用图灵机器人的自动回复演示目…

PHP定时抽奖怎么实现的,PHP 实现抽奖逻辑

public static function get_rand($proArr) {$result "";//概率数组的总概率精度$proSum array_sum($proArr);//概率数组循环foreach ($proArr as $key > $proCur) {$randNum mt_rand(1, $proSum);if ($randNum < $proCur) {$result $key;break;} else {$p…

绿盟漏洞扫描_主机安全漏洞解决方案

前几天发了一篇等保2.0的文章(等保2.0简单介绍 )&#xff0c;文章里面提到&#xff0c;相比于等保1.0标准&#xff0c;等保2.0很大幅度上对安全通用要求的一些控制项做了大幅精简&#xff0c;但是等保二级的要求仍多达135项、等保三级多达211项。https://mp.weixin.qq.com/s/kE…

采用光线跟踪绘制场景 c++_光线追踪的相干性聚集:硬件光线追踪的优势

尽管在理论上实现现代GPU的方法是无限的&#xff0c;但真正有效的方法是切实地了解问题并着手将方案变为现实。制造现代高性能半导体器件以及试图加速当前可编程光栅化技术所面临的问题揭示了GPU硬件行业发展的未来趋势。例如在现代GPU中SIMD处理和固定功能纹理单元是必不可少的…

xxljob 配置具体定时任务_分布式任务调度: XXL-Job

1 任务调度中心搭建、部署、任务管理与监控[1]任务调度中心页面2 SpringBoot 集成 xxl-job&#xff1a;创建调度任务maven项目pom.xml引入依赖:<dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>…

前端白屏问题_深入理解前端性能监控

在同样的网络环境下&#xff0c;有两个同样能满足你的需求的网站&#xff0c;一个唰的一下就加载出来了&#xff0c;另一个白屏转圈转了半天内容才出来&#xff0c;如果让你选择&#xff0c;你会用哪一个&#xff1f;页面的性能问题是前端开发中一个重要环节&#xff0c;但一直…

信号的采样与恢复matlab实验报告,实验七 连续信号的采样与恢复

一、实验目的通过MATLAB仿真验证抽样定理&#xff0c;进一步加深对抽样定理的理解。二、实验原理1. 连续信号的采样对某一连续时间信号f(t)的采样原理图为&#xff1a;由图可知&#xff0c;&#xff0c;其中&#xff0c;单位冲激采样信号的表达式为&#xff1a; 其傅里叶变换为…

treegrid 如何获取getchanges inserted_如何避开Vue性能优化之路的荆棘?

随着这几年前端技术快速发展&#xff0c;Vue框架在国内普及率极高&#xff0c;人人都会用&#xff0c;那Vue如何写得比别人优雅&#xff1f;如何写得比别人漂亮&#xff1f;鉴于一线互联网大厂在前沿技术领域的持续研究和大规模投入&#xff0c;直接向他们取经&#xff0c;是最…

matlab+信号+mpf,Python和Matlab中平均频率的差异

我有这个EMG signal&#xff0c;我想根据这个article绘制平均功率频率。我使用以下代码在Matlab中实现它&#xff1a;clear all;close all;EMGload(EMG.txt);N1000; %my windowz1;fs200 %sampling ratefor i1:length(EMG)-NDUM0;NUM0;FTfft(EMG(i:iN-1));psdFT.*conj(FT);NFFTl…

matlab和vlfeat关联,VLFeat在matlab和vs中安装

转&#xff1a;http://blog.csdn.net/u011718701/article/details/51452011博主最近用vlfeat库做课题&#xff0c;网上搜索使用方法&#xff0c;一大片都会告诉你说&#xff1a;run(/vl_setup) 然后就好啦哈哈哈哈哈哈~~~~~~~~~~~~~~But!理想很丰满&#xff0c;现实很骨感&…

document.createelement如何绑定点击事件_番外篇-EXCEL如何使用宏(VBA)

小编&#xff0c;会在后续推送一些关于VBA(宏)相关的文章(之前其实也推送了一些&#xff0c;其中也大概说了一下如何使用)&#xff0c;所以我们今天就专门写一篇如何使用宏&#xff0c;方便大家使用已经写好的宏。如何使用宏&#xff1a;常规宏VBA-一般都是此类1、调出-开发工具…

局域网打印机反应慢_为什么你的Excel这么慢,这些原因必须要知道!

Excel是很多人的高频办公工具&#xff0c;但大家或多或少地遇到过&#xff0c;有时自己电脑的Excel很慢&#xff0c;导致工作的效率不高&#xff0c;可能就会导致要加班加点&#xff0c;也压缩了自己其他方面的时间。本文将介绍一些常见的Excel”慢“的情况及其解决方案&#x…

linux挂载fc存储有超级坏块_Nand Flash基础知识与坏块管理机制的研究

欢迎FPGA工程师加入官方微信技术群点击蓝字关注我们FPGA之家-中国最好最大的FPGA纯工程师社群概述Flash名称的由来&#xff0c;Flash的擦除操作是以block块为单位的&#xff0c;与此相对应的是其他很多存储设备&#xff0c;是以bit位为最小读取/写入的单位&#xff0c;Flash是一…

carsim中质心加速度_振动CAE分析在空调压缩机支架设计中的应用

【摘要】本文运用有限元分析方法分析空调压缩机系统模态&#xff0c;并通过分析引起振动的激励源&#xff0c;找出压缩机支架和安装螺栓断裂的根本原因&#xff0c;并根据分析提出了解决措施。关键词&#xff1a;空调压缩机支架模态激励共振一、引言发动机轮系需要驱动的工作部…