网站开发人员工具种类,网站设置兼容模式怎么弄,住房和城乡建设部叉车证能用吗,律师事务所网站案例这几天由于工作需要#xff0c;对DBSCAN聚类算法进行了C的实现。时间复杂度O(n^2)#xff0c;主要花在算每个点领域内的点上。算法很简单#xff0c;现共享大家参考#xff0c;也希望有更多交流。数据点类型描述如下#xff1a;复制代码 代码如下:#include using namespac…这几天由于工作需要对DBSCAN聚类算法进行了C的实现。时间复杂度O(n^2)主要花在算每个点领域内的点上。算法很简单现共享大家参考也希望有更多交流。数据点类型描述如下复制代码 代码如下:#include using namespace std;const int DIME_NUM2; //数据维度为2全局常量//数据点类型class DataPoint{private:unsigned long dpID; //数据点IDdouble dimension[DIME_NUM]; //维度数据long clusterId; //所属聚类IDbool 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 i0; i{this-dimension[i]dimension[i];}}//设置维度数据void DataPoint::SetDimension(double* dimension){for(int i0; 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 i0; //数据个数统计while (! ifs.eof() ) //从文件中读取POI信息将POI信息写入POI列表中{DataPoint tempDP; //临时数据点对象double tempDimData[DIME_NUM]; //临时数据点维度信息for(int j0; j{ifstempDimData[j];}tempDP.SetDimension(tempDimData); //将维度信息存入数据点对象内//char date[20];//char time[20];double type; //无用信息//ifs date;//ifs time; //无用信息读入tempDP.SetDpId(i); //将数据点对象ID设置为itempDP.SetVisited(false); //数据点对象isVisited设置为falsetempDP.SetClusterId(-1); //设置默认簇ID为-1dadaSets.push_back(tempDP); //将对象压入数据集合容器i; //计数1}ifs.close(); //关闭文件流dataNum i; //设置数据对象集合大小为ifor(unsigned long i0; i{SetArrivalPoints(dadaSets[i]); //计算数据点领域内对象}return true; //返回}/*函数将已经过聚类算法处理的数据集合写回文件说明将已经过聚类结果写回文件参数char* fileName; //要写入的文件名返回值 true */bool ClusterAnalysis::WriteToFile(char* fileName ){ofstream of1(fileName); //初始化文件输出流for(unsigned long i0; i{for(int d0; dof1of1 dadaSets[i].GetClusterId() }of1.close(); //关闭输出文件流return true; //返回}/*函数设置数据点的领域点列表说明设置数据点的领域点列表参数返回值 true; */void ClusterAnalysis::SetArrivalPoints(DataPoint dp){for(unsigned long i0; i{double distance GetDistance(dadaSets[i], dp); //获取与特定点之间的距离if(distance radius i!dp.GetDpId()) //若距离小于半径并且特定点的id与dp的id不同执行dp.GetArrivalPoints().push_back(i); //将特定点id压力dp的领域列表中}if(dp.GetArrivalPoints().size() minPTs) //若dp领域内数据点数据量 minPTs执行{dp.SetKey(true); //将dp核心对象标志位设为truereturn; //返回}dp.SetKey(false); //若非核心对象则将dp核心对象标志位设为false}/*函数执行聚类操作说明执行聚类操作参数返回值 true; */bool ClusterAnalysis::DoDBSCANRecursive(){unsigned long clusterId0; //聚类id计数初始化为0for(unsigned long i0; i{DataPoint dpdadaSets[i]; //取到第i个数据点对象if(!dp.isVisited() dp.IsKey()) //若对象没被访问过并且是核心对象执行{dp.SetClusterId(clusterId); //设置该对象所属簇ID为clusterIddp.SetVisited(true); //设置该对象已被访问过KeyPointCluster(i,clusterId); //对该对象领域内点进行聚类clusterId; //clusterId自增1}//cout 孤立点\T i endl;}cout return true; //返回}/*函数对数据点领域内的点执行聚类操作说明采用递归的方法深度优先聚类数据参数unsigned long dpID; //数据点idunsigned long clusterId; //数据点所属簇id返回值 void; */void ClusterAnalysis::KeyPointCluster(unsigned long dpID, unsigned long clusterId ){DataPoint srcDp dadaSets[dpID]; //获取数据点对象if(!srcDp.IsKey()) return;vector arrvalPoints srcDp.GetArrivalPoints(); //获取对象领域内点ID列表for(unsigned long i0; i{DataPoint desDp dadaSets[arrvalPoints[i]]; //获取领域内点数据点if(!desDp.isVisited()) //若该对象没有被访问过执行{//cout 数据点\t desDp.GetDpId()desDp.SetClusterId(clusterId); //设置该对象所属簇的ID为clusterId即将该对象吸入簇中desDp.SetVisited(true); //设置该对象已被访问if(desDp.IsKey()) //若该对象是核心对象{KeyPointCluster(desDp.GetDpId(),clusterId); //递归地对该领域点数据的领域内的点执行聚类操作采用深度优先方法}}}}//两数据点之间距离/*函数获取两数据点之间距离说明获取两数据点之间的欧式距离参数DataPoint dp1; //数据点1DataPoint dp2; //数据点2返回值 double; //两点之间的距离 */double ClusterAnalysis::GetDistance(DataPoint dp1, DataPoint dp2){double distance 0; //初始化距离为0for(int i0; i{distance pow(dp1.GetDimension()[i] - dp2.GetDimension()[i],2); //距离每一维差的平方}return pow(distance,0.5); //开方并返回距离}算法调用就简单了复制代码 代码如下:#include ClusterAnalysis.h#include 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; //返回}