1. 程式人生 > >DBSCAN聚類演算法C++實現

DBSCAN聚類演算法C++實現

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

相關推薦

DBSCAN演算法C++實現

1 #include "ClusterAnalysis.h" 2 #include <fstream> 3 #include <iosfwd> 4 #include <math.h> 5 6 /* 7 函式:聚類初始化操作 8 說明:將資

K-menas演算法C++實現

基本介紹: k-means 演算法接受輸入量 k ;然後將n個數據物件劃分為 k個聚類以便使得所獲得的聚類滿足:同一聚類中的物件相似度較高;而不同聚類中的物件相似度較小。聚類相似度是利用各聚類中物件的均值所獲得一個“中心物件”(引力中心)來進行計算的。 工作過程:   k-m

DBSCAN演算法實現

設有N個樣本,樣本為p維, (1)計算距離矩陣D,時間複雜度為O(N*N*p); (2)對距離矩陣的每一行進行從小到大排序,得到SD(sorted D),時間複雜度為O(N*N*log(N)); (3)根據Eps與MinPts,標註核心點、邊界點和噪聲點。 首先比較SD(:

DBScan演算法Java實現

DBScan演算法流程圖 演算法:DBScan,基於密度的聚類演算法 輸入: D:一個包含n個數據的資料集 r:半徑引數 minPts:領域密度閾值 輸出:基於密度的聚類集合 標記D中所有的點為unvisted for each p i

模糊C均值演算法實現

模糊C均值聚類演算法的實現 研究背景 https://blog.csdn.net/liu_xiao_cheng/article/details/50471981    聚類分析是多元統計分析的一種,也是無監督模式識別的一個重要分支,在模式分類 影象處理和模糊

【無監督學習】DBSCAN演算法原理介紹,以及程式碼實現

前言:無監督學習想快一點複習完,就轉入有監督學習 聚類演算法主要包括哪些演算法?主要包括:K-m

模糊C均值演算法實現

 模糊C均值聚類演算法的實現 研究背景 聚類分析是多元統計分析的一種,也是無監督模式識別的一個重要分支,在模式分類 影象處理和模糊規則處理等眾多領域中獲得最廣泛的應用。它把一個沒有類別標記的樣本按照某種準則劃分為若干子集,使相似的樣本

DBSCAN演算法難嗎?我們來看看吧~

往期經典回顧 從零開始學Python【29】--K均值聚類(實戰部分) 從零開始學Python【28】--K均值聚類(理論部分) 從零開始學Python【27】--Logistic迴歸(實戰部分) 從零開始學Python【26】--Logistic迴歸(理論部分) 從零開始學Py

機器學習-*-DBSCAN及程式碼實現

DBSCAN DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪聲的基於密度的聚類方法) 原理 首先描述以下幾個概念,假設我們有資料集

DBSCAN演算法

1、演算法引入及簡介      為什麼要引入DBSCAN?      K均值聚類使用非常廣泛,作為古老的聚類方法,它的演算法非常簡單,而且速度很快。但是其缺點在於它不能識別非球形的簇;而DBS

機器學習 K-means 演算法 C++

筆記: 尚未解決的問題 :     1. 只支援二維,而不支援三維或更高,需要模板元     2. 尚未實現如何刪除極端點, 即預處理     3. 尚未視覺化 編譯環境 Ubuntu gcc 5.4 編譯選項  g++ -std=c++14 #include &l

k-medoid(k中心點)演算法Python實現

k-means演算法有個很大的缺點,就是對孤立點敏感性太高,孤立點即是脫離群眾的點,與眾不同的點,即在顯示中與其他點不是抱在一團的點。 為了體現兩者的不同,我特意溫習了一下知識,在構造初始點的時候,自己定義加入了幾個孤立點,使用k-means演算法跑的效果如下: 一開始的所有點:(可以看出其

一種改進的自適應快速AF-DBSCAN演算法

本人研究生期間寫的關於聚類演算法的一篇論文,已發表,希望對大家學習機器學習、資料探勘等相關研究有所幫助! 一種改進的自適應快速AF-DBSCAN聚類演算法 An Improved Adaptive and Fast AF-DBSCAN Clustering Algorit

層次演算法java實現

public class Node { String nodeName; // 樣本點名    Cluster cluster; // 樣本點所屬類簇    private double dimension[]; // 樣本點的維度    public Node(){    }    publ

演算法——python實現SOM演算法

演算法簡介 SOM網路是一種競爭學習型的無監督神經網路,將高維空間中相似的樣本點對映到網路輸出層中的鄰近神經元。 訓練過程簡述:在接收到訓練樣本後,每個輸出層神經元會計算該樣本與自身攜帶的權向量之間的距離,距離最近的神經元成為競爭獲勝者,稱為最佳匹配單元。然

k-means演算法——c語言

程式程式碼: #include"stdio.h" #include"stdlib.h" #include<iostream> using namespace std; #define N 11 #define k 3 typedef struc

K-means和PAM演算法Python實現及對比

K-means(K均值劃分)聚類:簡單的說,一般流程如下:先隨機選取k個點,將每個點分配給它們,得到最初的k個分類;在每個分類中計算均值,將點重新分配,劃歸到最近的中心點;重複上述步驟直到點的劃歸不再改變。下圖是K-means方法的示意。 PAM

模糊C均值以及C實現

1. 基本介紹     同K均值類似,FCM演算法也是一種基於劃分的聚類演算法,它的思想就是使得被劃分到同一簇的物件之間相似度最大,而不同簇之間的相似度最小。     模糊C均值是普通C均值聚類演算法的改進,普通C均值對資料進行硬性劃分,一個樣本一定明確的屬於某一類,FC

EM演算法matlab實現

最近看到了樸素貝葉斯定理,看著看著就看到了em聚類的演算法中(K-means聚類的原型)。 動手自己編個程式: %EM algorithm clc; clear; sigma = 1.5; miu1 = 3; miu2 = 7; N = 1000; x = zeros(1

NLP——Kmeans演算法簡單實現

本例中主要是對二維點進行距離計算,開始得時候選取兩個心,最終聚為兩簇。 結束條件的判斷有很多種,這裡採用的是最簡單的:當兩個心不再變化了,則停止聚類。 內部距離和可以不需要計算,這裡輸出來做結果評估用。 public class Km_w2 { //初始