久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

基于C 實現(xiàn)DBSCAN聚類算法

 飄渺o40uv5vs24 2023-02-13 發(fā)布于陜西

DBSCAN聚類算法進行了C++的實現(xiàn),,時間復(fù)雜度為O(n^2)。

1,、數(shù)據(jù)點類型描述如下(DataPoint.h)

  1. #include <vector>
  2. using namespace std;
  3. const int DIME_NUM=2; //數(shù)據(jù)維度為2,全局常量
  4. //數(shù)據(jù)點類型
  5. class DataPoint
  6. {
  7. private:
  8. unsigned long dpID; //數(shù)據(jù)點ID
  9. double dimension[DIME_NUM]; //維度數(shù)據(jù)
  10. long clusterId; //所屬聚類ID
  11. bool isKey; //是否核心對象
  12. bool visited; //是否已訪問
  13. vector<unsigned long> arrivalPoints; //領(lǐng)域數(shù)據(jù)點id列表
  14. public:
  15. DataPoint(); //默認構(gòu)造函數(shù)
  16. DataPoint(unsigned long dpID,double* dimension , bool isKey); //構(gòu)造函數(shù)
  17. unsigned long GetDpId(); //GetDpId方法
  18. void SetDpId(unsigned long dpID); //SetDpId方法
  19. double* GetDimension(); //GetDimension方法
  20. void SetDimension(double* dimension); //SetDimension方法
  21. bool IsKey(); //GetIsKey方法
  22. void SetKey(bool isKey); //SetKey方法
  23. bool isVisited(); //GetIsVisited方法
  24. void SetVisited(bool visited); //SetIsVisited方法
  25. long GetClusterId(); //GetClusterId方法
  26. void SetClusterId(long classId); //SetClusterId方法
  27. vector<unsigned long>& GetArrivalPoints(); //GetArrivalPoints方法
  28. };

2,、對應(yīng)實現(xiàn)(DataPoint.cpp)

  1. #include 'DataPoint.h'
  2. //默認構(gòu)造函數(shù)
  3. DataPoint::DataPoint()
  4. {
  5. }
  6. //構(gòu)造函數(shù)
  7. DataPoint::DataPoint(unsigned long dpID,double* dimension , bool isKey):isKey(isKey),dpID(dpID)
  8. {
  9. //傳遞每維的維度數(shù)據(jù)
  10. for(int i=0; i<DIME_NUM;i++)
  11. {
  12. this->dimension[i]=dimension[i];
  13. }
  14. }
  15. //設(shè)置維度數(shù)據(jù)
  16. void DataPoint::SetDimension(double* dimension)
  17. {
  18. for(int i=0; i<DIME_NUM;i++)
  19. {
  20. this->dimension[i]=dimension[i];
  21. }
  22. }
  23. //獲取維度數(shù)據(jù)
  24. double* DataPoint::GetDimension()
  25. {
  26. return this->dimension;
  27. }
  28. //獲取是否為核心對象
  29. bool DataPoint::IsKey()
  30. {
  31. return this->isKey;
  32. }
  33. //設(shè)置核心對象標志
  34. void DataPoint::SetKey(bool isKey)
  35. {
  36. this->isKey = isKey;
  37. }
  38. //獲取DpId方法
  39. unsigned long DataPoint::GetDpId()
  40. {
  41. return this->dpID;
  42. }
  43. //設(shè)置DpId方法
  44. void DataPoint::SetDpId(unsigned long dpID)
  45. {
  46. this->dpID = dpID;
  47. }
  48. //GetIsVisited方法
  49. bool DataPoint::isVisited()
  50. {
  51. return this->visited;
  52. }
  53. //SetIsVisited方法
  54. void DataPoint::SetVisited( bool visited )
  55. {
  56. this->visited = visited;
  57. }
  58. //GetClusterId方法
  59. long DataPoint::GetClusterId()
  60. {
  61. return this->clusterId;
  62. }
  63. //SetClusterId方法
  64. void DataPoint::SetClusterId( long clusterId )
  65. {
  66. this->clusterId = clusterId;
  67. }
  68. //GetArrivalPoints方法
  69. vector<unsigned long>& DataPoint::GetArrivalPoints()
  70. {
  71. return arrivalPoints;
  72. }

3,、DBSCAN算法類型描述(ClusterAnalysis.h)

  1. #include <iostream>
  2. #include <cmath>
  3. #include 'DataPoint.h'
  4. #include<QVector>
  5. using namespace std;
  6. //聚類分析類型
  7. class ClusterAnalysis
  8. {
  9. private:
  10. vector<DataPoint> dadaSets; //數(shù)據(jù)集合
  11. unsigned int dimNum; //維度
  12. double radius; //半徑
  13. unsigned int dataNum; //數(shù)據(jù)數(shù)量
  14. unsigned int minPTs; //鄰域最小數(shù)據(jù)個數(shù)
  15. double GetDistance(DataPoint& dp1, DataPoint& dp2); //距離函數(shù)
  16. void SetArrivalPoints(DataPoint& dp); //設(shè)置數(shù)據(jù)點的領(lǐng)域點列表
  17. void KeyPointCluster( unsigned long i, unsigned long clusterId ); //對數(shù)據(jù)點領(lǐng)域內(nèi)的點執(zhí)行聚類操作
  18. public:
  19. ClusterAnalysis(){} //默認構(gòu)造函數(shù)
  20. bool Init(QVector<QVector<QString>> Data, double radius, int minPTs); //初始化操作
  21. unsigned long DoDBSCANRecursive(); //DBSCAN遞歸算法
  22. bool WriteToFile(char* fileName); //將聚類結(jié)果寫入文件
  23. };

4、算法實現(xiàn)(ClusterAnalysis.cpp)

  1. #include 'ClusterAnalysis.h'
  2. #include <fstream>
  3. #include <iosfwd>
  4. #include <math.h>
  5. /*
  6. 函數(shù):聚類初始化操作
  7. 說明:將數(shù)據(jù)文件名,,半徑,,領(lǐng)域最小數(shù)據(jù)個數(shù)信息寫入聚類算法類,,讀取文件,把數(shù)據(jù)信息讀入寫進算法類數(shù)據(jù)集合中
  8. 參數(shù):
  9. QVector<QVector<QString>> Data; //數(shù)據(jù)
  10. double radius; //半徑
  11. int minPTs; //領(lǐng)域最小數(shù)據(jù)個數(shù)
  12. 返回值: true; */
  13. bool ClusterAnalysis::Init(char* fileName, double radius, int minPTs)
  14. {
  15. this->radius = radius; //設(shè)置半徑
  16. this->minPTs = minPTs; //設(shè)置領(lǐng)域最小數(shù)據(jù)個數(shù)
  17. this->dimNum = DIME_NUM; //設(shè)置數(shù)據(jù)維度
  18. ifstream ifs(fileName); //打開文件
  19. if (! ifs.is_open()) //若文件已經(jīng)被打開,,報錯誤信息
  20. {
  21. cout << 'Error opening file'; //輸出錯誤信息
  22. exit (-1); //程序退出
  23. }
  24. unsigned long i=0; //數(shù)據(jù)個數(shù)統(tǒng)計
  25. while (! ifs.eof() ) //從文件中讀取POI信息,,將POI信息寫入POI列表中
  26. {
  27. DataPoint tempDP; //臨時數(shù)據(jù)點對象
  28. double tempDimData[DIME_NUM]; //臨時數(shù)據(jù)點維度信息
  29. for(int j=0; j<DIME_NUM; j++) //讀文件,讀取每一維數(shù)據(jù)
  30. {
  31. ifs>>tempDimData[j];
  32. }
  33. tempDP.SetDimension(tempDimData); //將維度信息存入數(shù)據(jù)點對象內(nèi)
  34. //char date[20]='';
  35. //char time[20]='';
  36. double type; //無用信息
  37. //ifs >> date;
  38. //ifs >> time; //無用信息讀入
  39. tempDP.SetDpId(i); //將數(shù)據(jù)點對象ID設(shè)置為i
  40. tempDP.SetVisited(false); //數(shù)據(jù)點對象isVisited設(shè)置為false
  41. tempDP.SetClusterId(-1); //設(shè)置默認簇ID為-1
  42. dadaSets.push_back(tempDP); //將對象壓入數(shù)據(jù)集合容器
  43. i++; //計數(shù)+1
  44. }
  45. ifs.close(); //關(guān)閉文件流
  46. dataNum =i; //設(shè)置數(shù)據(jù)對象集合大小為i
  47. for(unsigned long i=0; i<dataNum;i++)
  48. {
  49. SetArrivalPoints(dadaSets[i]); //計算數(shù)據(jù)點領(lǐng)域內(nèi)對象
  50. }
  51. return true; //返回
  52. }
  53. /*
  54. 函數(shù):將已經(jīng)過聚類算法處理的數(shù)據(jù)集合寫回文件
  55. 說明:將已經(jīng)過聚類結(jié)果寫回文件
  56. 參數(shù):
  57. char* fileName; //要寫入的文件名
  58. 返回值: true */
  59. bool ClusterAnalysis::WriteToFile(char* fileName )
  60. {
  61. ofstream of1(fileName); //初始化文件輸出流
  62. for(unsigned long i=0; i<dataNum;i++) //對處理過的每個數(shù)據(jù)點寫入文件
  63. {
  64. for(int d=0; d<DIME_NUM ; d++) //將維度信息寫入文件
  65. of1<<dadaSets[i].GetDimension()[d]<<'\t';
  66. of1 << dadaSets[i].GetClusterId() <<endl; //將所屬簇ID寫入文件
  67. }
  68. of1.close(); //關(guān)閉輸出文件流
  69. return true; //返回
  70. }
  71. /*
  72. 函數(shù):設(shè)置數(shù)據(jù)點的領(lǐng)域點列表
  73. 說明:設(shè)置數(shù)據(jù)點的領(lǐng)域點列表
  74. 參數(shù):
  75. 返回值: true; */
  76. void ClusterAnalysis::SetArrivalPoints(DataPoint& dp)
  77. {
  78. for(unsigned long i=0; i<dataNum; i++) //對每個數(shù)據(jù)點執(zhí)行
  79. {
  80. double distance =GetDistance(dadaSets[i], dp); //獲取與特定點之間的距離
  81. if(distance <= radius && i!=dp.GetDpId()) //若距離小于半徑,,并且特定點的id與dp的id不同執(zhí)行
  82. dp.GetArrivalPoints().push_back(i); //將特定點id壓力dp的領(lǐng)域列表中
  83. }
  84. if(dp.GetArrivalPoints().size() >= minPTs) //若dp領(lǐng)域內(nèi)數(shù)據(jù)點數(shù)據(jù)量> minPTs執(zhí)行
  85. {
  86. dp.SetKey(true); //將dp核心對象標志位設(shè)為true
  87. return; //返回
  88. }
  89. dp.SetKey(false); //若非核心對象,,則將dp核心對象標志位設(shè)為false
  90. }
  91. /*
  92. 函數(shù):執(zhí)行聚類操作
  93. 說明:執(zhí)行聚類操作
  94. 參數(shù):
  95. 返回值: true; */
  96. unsigned long ClusterAnalysis::DoDBSCANRecursive()
  97. {
  98. unsigned long clusterId=0; //聚類id計數(shù),初始化為0
  99. for(unsigned long i=0; i<dataNum;i++) //對每一個數(shù)據(jù)點執(zhí)行
  100. {
  101. DataPoint& dp=dadaSets[i]; //取到第i個數(shù)據(jù)點對象
  102. if(!dp.isVisited() && dp.IsKey()) //若對象沒被訪問過,,并且是核心對象執(zhí)行
  103. {
  104. dp.SetClusterId(clusterId); //設(shè)置該對象所屬簇ID為clusterId
  105. dp.SetVisited(true); //設(shè)置該對象已被訪問過
  106. KeyPointCluster(i,clusterId); //對該對象領(lǐng)域內(nèi)點進行聚類
  107. clusterId++; //clusterId自增1
  108. }
  109. //cout << '孤立點\T' << i << endl;
  110. }
  111. // cout <<'共聚類' <<clusterId<<'個'<< endl; //算法完成后,,輸出聚類個數(shù)
  112. return clusterId; //返回
  113. }
  114. /*
  115. 函數(shù):對數(shù)據(jù)點領(lǐng)域內(nèi)的點執(zhí)行聚類操作
  116. 說明:采用遞歸的方法,深度優(yōu)先聚類數(shù)據(jù)
  117. 參數(shù):
  118. unsigned long dpID; //數(shù)據(jù)點id
  119. unsigned long clusterId; //數(shù)據(jù)點所屬簇id
  120. 返回值: void; */
  121. void ClusterAnalysis::KeyPointCluster(unsigned long dpID, unsigned long clusterId )
  122. {
  123. DataPoint& srcDp = dadaSets[dpID]; //獲取數(shù)據(jù)點對象
  124. if(!srcDp.IsKey()) return;
  125. vector<unsigned long>& arrvalPoints = srcDp.GetArrivalPoints(); //獲取對象領(lǐng)域內(nèi)點ID列表
  126. for(unsigned long i=0; i<arrvalPoints.size(); i++)
  127. {
  128. DataPoint& desDp = dadaSets[arrvalPoints[i]]; //獲取領(lǐng)域內(nèi)點數(shù)據(jù)點
  129. if(!desDp.isVisited()) //若該對象沒有被訪問過執(zhí)行
  130. {
  131. //cout << '數(shù)據(jù)點\t'<< desDp.GetDpId()<<'聚類ID為\t' <<clusterId << endl;
  132. desDp.SetClusterId(clusterId); //設(shè)置該對象所屬簇的ID為clusterId,,即將該對象吸入簇中
  133. desDp.SetVisited(true); //設(shè)置該對象已被訪問
  134. if(desDp.IsKey()) //若該對象是核心對象
  135. {
  136. KeyPointCluster(desDp.GetDpId(),clusterId); //遞歸地對該領(lǐng)域點數(shù)據(jù)的領(lǐng)域內(nèi)的點執(zhí)行聚類操作,,采用深度優(yōu)先方法
  137. }
  138. }
  139. }
  140. }
  141. //兩數(shù)據(jù)點之間距離
  142. /*
  143. 函數(shù):獲取兩數(shù)據(jù)點之間距離
  144. 說明:獲取兩數(shù)據(jù)點之間的歐式距離
  145. 參數(shù):
  146. DataPoint& dp1; //數(shù)據(jù)點1
  147. DataPoint& dp2; //數(shù)據(jù)點2
  148. 返回值: double; //兩點之間的距離 */
  149. double ClusterAnalysis::GetDistance(DataPoint& dp1, DataPoint& dp2)
  150. {
  151. double distance =0; //初始化距離為0
  152. for(int i=0; i<DIME_NUM;i++) //對數(shù)據(jù)每一維數(shù)據(jù)執(zhí)行
  153. {
  154. distance += pow(dp1.GetDimension()[i] - dp2.GetDimension()[i],2); //距離+每一維差的平方
  155. }
  156. return pow(distance,0.5); //開方并返回距離
  157. }

5、算法調(diào)用

input.txt文件內(nèi)容 根據(jù)myClusterAnalysis.Init方法自行構(gòu)建,。

  1. #include 'ClusterAnalysis.h'
  2. #include <cstdio>
  3. using namespace std;
  4. int main()
  5. {
  6. ClusterAnalysis myClusterAnalysis; //聚類算法對象聲明
  7. myClusterAnalysis.Init('input.txt',100,5); //算法初始化操作,,指定半徑為100,,領(lǐng)域內(nèi)最小數(shù)據(jù)點個數(shù)為5
  8. myClusterAnalysis.DoDBSCANRecursive(); //執(zhí)行聚類算法
  9. myClusterAnalysis.WriteToFile('out.txt');//寫執(zhí)行后的結(jié)果寫入文件
  10. system('pause'); //顯示結(jié)果
  11. return 0; //返回
  12. }

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多