logo资料库

用C++实现DBSCAN聚类算法.pdf

第1页 / 共6页
第2页 / 共6页
第3页 / 共6页
第4页 / 共6页
第5页 / 共6页
第6页 / 共6页
资料共6页,全文预览结束
用用C++实现实现DBSCAN聚类算法 聚类算法 本篇文章是对使用C++实现DBSCAN聚类算法的方法进行了详细的分析介绍,需要的朋友参考下 这几天由于工作需要,对DBSCAN聚类算法进行了C++的实现。时间复杂度O(n^2),主要花在算每个点领域内的点上。算法 很简单,现共享大家参考,也希望有更多交流。 数据点类型描述如下: 数据点类型描述如下: 复制代码 代码如下: #include using namespace std; const int DIME_NUM=2; //数据维度为2,全局常量 //数据点类型 class DataPoint { private: unsigned long dpID; //数据点ID double dimension[DIME_NUM]; //维度数据 long clusterId; //所属聚类ID bool isKey; //是否核心对象 bool visited; //是否已访问 vector arrivalPoints; //领域数据点id列表 public: DataPoint(); //默认构造函数 DataPoint(unsigned long dpID,double* dimension , bool isKey); //构造函数 unsigned long GetDpId(); //GetDpId方法 void SetDpId(unsigned long dpID); //SetDpId方法 double* GetDimension(); //GetDimension方法 void SetDimension(double* dimension); //SetDimension方法 bool IsKey(); //GetIsKey方法 void SetKey(bool isKey); //SetKey方法 bool isVisited(); //GetIsVisited方法 void SetVisited(bool visited); //SetIsVisited方法 long GetClusterId(); //GetClusterId方法 void SetClusterId(long classId); //SetClusterId方法 vector& GetArrivalPoints(); //GetArrivalPoints方法 }; 这是实现: 复制代码 代码如下: #include "DataPoint.h" //默认构造函数 DataPoint::DataPoint() { } //构造函数 DataPoint::DataPoint(unsigned long dpID,double* dimension , bool isKey):isKey(isKey),dpID(dpID) { //传递每维的维度数据 for(int i=0; idimension[i]=dimension[i]; } } //设置维度数据 void DataPoint::SetDimension(double* dimension) { for(int i=0; i
this->dimension[i]=dimension[i]; } } //获取维度数据 double* DataPoint::GetDimension() { return this->dimension; } //获取是否为核心对象 bool DataPoint::IsKey() { return this->isKey; } //设置核心对象标志 void DataPoint::SetKey(bool isKey) { this->isKey = isKey; } //获取DpId方法 unsigned long DataPoint::GetDpId() { return this->dpID; } //设置DpId方法 void DataPoint::SetDpId(unsigned long dpID) { this->dpID = dpID; } //GetIsVisited方法 bool DataPoint::isVisited() { return this->visited; } //SetIsVisited方法 void DataPoint::SetVisited( bool visited ) { this->visited = visited; } //GetClusterId方法 long DataPoint::GetClusterId() { return this->clusterId; } //GetClusterId方法 void DataPoint::SetClusterId( long clusterId ) { this->clusterId = clusterId; } //GetArrivalPoints方法 vector& DataPoint::GetArrivalPoints() { return arrivalPoints; } DBSCAN算法类型描述: 复制代码 代码如下:
#include #include using namespace std; //聚类分析类型 class ClusterAnalysis { private: vector dadaSets; //数据集合 unsigned int dimNum; //维度 double radius; //半径 unsigned int dataNum; //数据数量 unsigned int minPTs; //邻域最小数据个数 double GetDistance(DataPoint& dp1, DataPoint& dp2); //距离函数 void SetArrivalPoints(DataPoint& dp); //设置数据点的领域点列表 void KeyPointCluster( unsigned long i, unsigned long clusterId ); //对数据点领域内的点执行聚类操作 public: ClusterAnalysis(){} //默认构造函数 bool Init(char* fileName, double radius, int minPTs); //初始化操作 bool DoDBSCANRecursive(); //DBSCAN递归算法 bool WriteToFile(char* fileName); //将聚类结果写入文件 }; 聚类实现: 复制代码 代码如下: #include "ClusterAnalysis.h" #include #include #include /* 函数:聚类初始化操作 说明:将数据文件名,半径,领域最小数据个数信息写入聚类算法类,读取文件,把数据信息读入写进算法类数据集合中 参数: char* fileName; //文件名 double radius; //半径 int minPTs; //领域最小数据个数 返回值: true; */ bool ClusterAnalysis::Init(char* fileName, double radius, int minPTs) { this->radius = radius; //设置半径 this->minPTs = minPTs; //设置领域最小数据个数 this->dimNum = DIME_NUM; //设置数据维度 ifstream ifs(fileName); //打开文件 if (! ifs.is_open()) //若文件已经被打开,报错误信息 { cout << "Error opening file"; //输出错误信息 exit (-1); //程序退出 } unsigned long i=0; //数据个数统计 while (! ifs.eof() ) //从文件中读取POI信息,将POI信息写入POI列表中 { DataPoint tempDP; //临时数据点对象 double tempDimData[DIME_NUM]; //临时数据点维度信息 for(int j=0; j>tempDimData[j]; } tempDP.SetDimension(tempDimData); //将维度信息存入数据点对象内 //char date[20]=""; //char time[20]=""; ////double type; //无用信息
//ifs >> date; //ifs >> time; //无用信息读入 tempDP.SetDpId(i); //将数据点对象ID设置为i tempDP.SetVisited(false); //数据点对象isVisited设置为false tempDP.SetClusterId(-1); //设置默认簇ID为-1 dadaSets.push_back(tempDP); //将对象压入数据集合容器 i++; //计数+1 } ifs.close(); //关闭文件流 dataNum =i; //设置数据对象集合大小为i for(unsigned long i=0; i= minPTs) //若dp领域内数据点数据量> minPTs执行 { dp.SetKey(true); //将dp核心对象标志位设为true return; //返回 } dp.SetKey(false); //若非核心对象,则将dp核心对象标志位设为false } /* 函数:执行聚类操作 说明:执行聚类操作 参数: 返回值: true; */ bool ClusterAnalysis::DoDBSCANRecursive() { unsigned long clusterId=0; //聚类id计数,初始化为0 for(unsigned long i=0; i
{ DataPoint& dp=dadaSets[i]; //取到第i个数据点对象 if(!dp.isVisited() && dp.IsKey()) //若对象没被访问过,并且是核心对象执行 { dp.SetClusterId(clusterId); //设置该对象所属簇ID为clusterId dp.SetVisited(true); //设置该对象已被访问过 KeyPointCluster(i,clusterId); //对该对象领域内点进行聚类 clusterId++; //clusterId自增1 } //cout << "孤立点\T" << i << endl; } cout <<"共聚类" <& arrvalPoints = srcDp.GetArrivalPoints(); //获取对象领域内点ID列表 for(unsigned long i=0; i
using namespace std; int main() { ClusterAnalysis myClusterAnalysis; //聚类算法对象声明 myClusterAnalysis.Init("D:\\1108\\XY.txt",500,9); //算法初始化操作,指定半径为15,领域内最小数据点个数为3, (在程序中已指定数据维度为2) myClusterAnalysis.DoDBSCANRecursive(); //执行聚类算法 myClusterAnalysis.WriteToFile("D:\\1108\\XYResult.txt");//写执行后的结果写入文件 system("pause"); //显示结果 return 0; //返回 }
分享到:
收藏