聚类算法--近邻聚类算法(C++实现)
聚类算法–近邻聚类算法(C++实现)
写在前面:
最近邻聚类算法,应该不是KNN,也不是K-means,就是一个特别基础的算法,但是在CSDN没有找到C++实现的这个算法,只有一个python写的(https://blog.csdn.net/Ha_hha/article/details/79128777),于是自己写了一个,目前还有错误,相同数据多次运行的结果不一样,希望有大佬可以指出是哪里有问题
算法介绍:
代码介绍:
用的vector存放内容,sampoint 存放样本点,clucenter存放聚类中心点。
在测试版输入样本点有两中方式,一个是样本点随机生成,一个是自己输入。
第一个聚类中心点随机生成。
euclidean_clu函数用来计算样本点和当前已有的聚类中心的欧式距离,如果样本点和每个聚类中心的距离都大于阈值T,就增加新的聚类中心,同时退出当前循环,重新执行当前函数。当该函数执行完,说明已经找到了全部的聚类中心。
euclidean_step再次计算所有样本点和聚类中心点的距离,找到距离样本点最近的一个聚类中心,进行分类,这里用了map存放。同时该函数输出最后的结果。
代码(纯净版):
#include <bits/stdc++.h>
using namespace std;vector<vector<long long >> sampoint;
vector<vector<long long >> clucenter;
long long n,v,T,random_num;void euclidean_clu();
void append_clu(long long x);
void euclidean_step();
int main(){/*1.输入数据*/long long temp;cout<<"输入样本个数和维度:"<<endl;cin>>n>>v; //输入样本个数和维度 cout<<"输入阈值T:"<<endl;cin>>T;vector<long long > intemp_clu;long long temp_n=n;cout<<"随机生成的样本点如下:"<<endl;while(n--){for(long long i=0;i<v;i++){temp=rand()%100;intemp_clu.push_back(temp);}sampoint.push_back(intemp_clu);intemp_clu.clear(); //每次输入完成都要清空,否则之前的数据会保留 }n=temp_n;/*输出测试*/for(long long i=0;i<temp_n;i++){for(long long j=0;j<v;j++){cout<<sampoint[i][j]<<" ";}cout<<endl;}/*2.获取第一个聚类中心,并在样本点中删除聚类中心*/long long temp_random;vector<long long > first_clucenter;temp_random=rand()%sampoint.size();for(long long i=0;i<v;i++){first_clucenter.push_back(sampoint[temp_random][i]);} sampoint.erase(sampoint.begin()+temp_random);clucenter.push_back(first_clucenter);cout<<endl;euclidean_clu();euclidean_step();}
void euclidean_clu(){for(long long i=0;i<sampoint.size();i++){long long temp_dean=0,min_dean=1000000,min_clu=0,min_sam;for(long long j=0;j<clucenter.size();j++){for(long long k=0;k<v;k++){ temp_dean+=pow((sampoint[i][k]-clucenter[j][k]),2);}temp_dean=sqrt(temp_dean);if(temp_dean>T){ append_clu(i);euclidean_clu(); //加入新的中心点后重新进行欧氏距离的计算 } temp_dean=0;
}
}
return ;
}/*4.增加聚类中心点*/
void append_clu(long long x){clucenter.push_back(sampoint[x]);sampoint.erase(sampoint.begin()+x);
}
/*对样本点根据已有的聚类中心进行划分*/
void euclidean_step(){long long temp_dean=0,min_dean=1000000,min_clu=0;map<long long ,long long > pdean;for(long long i=0;i<sampoint.size();i++){temp_dean=0,min_dean=1000000,min_clu=0;for(long long j=0;j<clucenter.size();j++){for(long long k=0;k<v;k++){ temp_dean+=pow((sampoint[i][k]-clucenter[j][k]),2);}if(temp_dean<min_dean){ //取最小的距离和对应的聚类中心 min_dean=temp_dean;min_clu=j;} temp_dean=0;}pdean.insert({i,min_clu});}cout<<"总共有"<<clucenter.size()<<"个聚类中心:"<<endl;for(long long i=0;i<clucenter.size();i++){for(long long j=0;j<v;j++){cout<<clucenter[i][j]<<" ";}cout<<endl;}cout<<endl;for(long long i=0;i<clucenter.size();i++){cout<<"第"<<i+1<<"类样本点:"<<endl;cout<<"(";for(long long j=0;j<v;j++){cout<<clucenter[i][j]<<" ";}cout<<")";cout<<endl;for(auto it=pdean.begin();it!=pdean.end();it++){if((*it).second==i){cout<<"(";for(long long j=0;j<v;j++){cout<<sampoint[(*it).first][j]<<" ";}cout<<") ";}}cout<<endl;}}
代码(测试用):
#include <bits/stdc++.h>
using namespace std;vector<vector<long long>> sampoint;
vector<vector<long long>> clucenter;
long long n,v,T,random_num;void euclidean_clu();
void append_clu(long long x);
void euclidean_step();
int main(){/*1.输入数据*/long long temp;cout<<"输入样本个数和维度:"<<endl;cin>>n>>v; //输入样本个数和维度 cout<<"输入阈值T:"<<endl;cin>>T;vector<long long> intemp_clu;long long temp_n=n;cout<<"随机生成的样本点如下:"<<endl;while(n--){for(long long i=0;i<v;i++){// cin>>temp;temp=rand()%100;intemp_clu.push_back(temp);//cout<<long longemp_clu[long longemp_clu.size()-1]<<endl;}sampoint.push_back(intemp_clu);intemp_clu.clear(); //每次输入完成都要清空,否则之前的数据会保留 }n=temp_n;/*输出测试*/for(long long i=0;i<temp_n;i++){for(long long j=0;j<v;j++){cout<<sampoint[i][j]<<" ";}cout<<endl;}/*2.获取第一个聚类中心,并在样本点中删除聚类中心*/long long temp_random;vector<long long> first_clucenter;temp_random=rand()%sampoint.size();//cout<<temp_random<<endl;for(long long i=0;i<v;i++){first_clucenter.push_back(sampoint[temp_random][i]);} sampoint.erase(sampoint.begin()+temp_random);clucenter.push_back(first_clucenter);cout<<"生成的第一个聚类中心点是:"<<endl;for(long long i=0;i<v;i++){cout<<clucenter[0][i]<<" ";}cout<<endl;/*first_clucenter.clear(); //测试是否成功删除聚点的样本点 for(long long i=0;i<temp_n;i++){for(long long j=0;j<v;j++){cout<<sampoint[i][j]<<" ";}cout<<endl;}*/euclidean_clu();cout<<"over"<<endl;euclidean_step();//std::cout << "The run time is: " <<(double)clock() / CLOCKS_PER_SEC << "s" << std::endl;//printf("Time used = %.2f\n", (double)clock() / CLOCKS_PER_SEC);
}/*3.计算各样本点到聚类中心的欧式距离,函数实现*/
void euclidean_clu(){vector<long long> all_dean;
// cout<<sampoint.size()<<endl; /*输出样本点的个数*/long long temp_x=0;for(long long i=0;i<sampoint.size();i++){long long temp_dean=0,min_dean=1000000,min_clu=0,min_sam;for(long long j=0;j<clucenter.size();j++){for(long long k=0;k<v;k++){ temp_dean+=(sampoint[i][k]-clucenter[j][k])*(sampoint[i][k]-clucenter[j][k]);}/*得到样本点和某聚类中心点的距离之后,判断是否大于阈值,如果大于,则成为新的聚类中心点*/// cout<<temp_dean<<" "<<i<<" "<<j<<endl; //输出各个样本点和聚类中心的欧氏距离 temp_x=sqrt(temp_dean);temp_dean=0;// cout<<"temp_x:"<<temp_x<<endl;all_dean.push_back(temp_x);/* if(long long(sqrt(temp_dean))>T){cout<<j<<endl;cout<<temp_dean<<" "<<long long(sqrt(temp_dean))<<" "<<i<<" "<<j<<endl; //cout<<"出现新的聚类中心"<<endl; append_clu(i);*/ //测试用 /*for(long long i=0;i<sampoint.size();i++){for(long long j=0;j<v;j++){cout<<sampoint[i][j]<<" ";}cout<<endl;}*/// euclidean_clu(); //加入新的中心点后重新进行欧氏距离的计算// return ; } bool bool_clu=true;for(long long a=0;a<all_dean.size();a++){// cout<<all_dean[i]<<" ";if(all_dean[i]<T){bool_clu=false;break;}}all_dean.clear();if(bool_clu){//cout<<"出现新的聚类中心"<<endl; append_clu(i);euclidean_clu(); //加入新的中心点后重新进行欧氏距离的计算return ; }//cout<<temp_dean<<endl;
/* if(temp_dean<min_dean){ //取最小的距离和对应的聚类中心 min_dean=temp_dean;min_clu=j;}temp_dean=0; }cout<<i<<" "<<min_clu<<" "<<" "<<min_dean<<endl;pdean.insert({i,min_clu});}return ;
}
*/
}
return ;
}/*4.增加聚类中心点*/
void append_clu(long long x){clucenter.push_back(sampoint[x]);
/* cout<<"加入新的聚类中心:";for(long long i=0;i<v;i++){cout<<sampoint[x][i]<<" ";}
*/
// cout<<"加入了新的聚类中心"<<endl;if(x==sampoint.size()-1){sampoint.pop_back();// cout<<"最后一个"<<endl;}else{sampoint.erase(sampoint.begin()+x);}return ;}
/*对样本点根据已有的聚类中心进行划分*/
void euclidean_step(){/* 测试用cout<<"聚类中心点为:"<<endl;for(long long i=0;i<clucenter.size();i++){for(long long j=0;j<v;j++){cout<<clucenter[i][j]<<" ";}cout<<endl;} *//* cout<<endl;for(long long i=0;i<sampoint.size();i++){for(long long j=0;j<v;j++){cout<<sampoint[i][j]<<" ";}cout<<endl;}*/long long temp_dean=0,min_dean=10000,min_clu=0;map<long long,long long> pdean;for(long long i=0;i<sampoint.size();i++){temp_dean=0,min_dean=10000,min_clu=0;for(long long j=0;j<clucenter.size();j++){for(long long k=0;k<v;k++){ temp_dean+=pow((sampoint[i][k]-clucenter[j][k]),2);}//cout<<temp_dean<<endl;if(temp_dean<min_dean){ //取最小的距离和对应的聚类中心 min_dean=temp_dean;min_clu=j;} //cout<<i<<" "<<min_clu<<" "<<" "<<min_dean<<endl;temp_dean=0;}pdean.insert({i,min_clu});}/*for(auto it=pdean.begin();it!=pdean.end();it++){cout<<(*it).first<<" "<<(*it).second<<endl;}*/cout<<"总共有"<<clucenter.size()<<"个聚类中心:"<<endl;for(long long i=0;i<clucenter.size();i++){for(long long j=0;j<v;j++){cout<<clucenter[i][j]<<" ";}cout<<endl;}cout<<endl;for(long long i=0;i<clucenter.size();i++){cout<<"第"<<i+1<<"类样本点:";cout<<"{";cout<<"(";for(long long j=0;j<v;j++){cout<<clucenter[i][j]<<" ";}cout<<")";
// cout<<endl;for(auto it=pdean.begin();it!=pdean.end();it++){if((*it).second==i){cout<<"(";for(long long j=0;j<v;j++){cout<<sampoint[(*it).first][j]<<" ";}cout<<") ";}}cout<<"}";
// cout<<endl;}}
写在最后:
ldu模式识别,代码仅作学习参考使用,
聚类算法--近邻聚类算法(C++实现)相关推荐
- java实现近邻聚类算法,近邻传播聚类算法 - osc_t74tdxrl的个人空间 - OSCHINA - 中文开源技术交流社区...
近邻传播聚类算法 1.算法简介 AP(Affinity Propagation)通常被翻译为近邻传播算法或者仿射传播算法,是在2007年的Science杂志上提出的一种新的聚类算法.AP算法的基本思想 ...
- python音频聚类_Python实现聚类算法AP
1.算法简介 AP(Affinity Propagation)通常被翻译为近邻传播算法或者亲和力传播算法,是在2007年的Science杂志上提出的一种新的聚类算法.AP算法的基本思想是将全部数据点都 ...
- 机器学习算法之 K-means、层次聚类,谱聚类
k-means 和层次聚类都属于划分聚类,实际中最常用的是k-means,k-means效果不好的情况下才会采用其他聚类 K-means算法 K-means算法,也称为K-平均或者K-均值,是一种使用 ...
- 聚类方法:DBSCAN算法研究
DBSCAN聚类算法三部分: 1. DBSCAN原理.流程.参数设置.优缺点以及算法: http://blog.csdn.net/zhouxianen1987/article/detai ...
- 聚类算法实践——谱聚类、Chameleon聚类
转载自:http://www.itongji.cn/article/0R52D42013.html 上一篇文章里说到的层次聚类和K-means聚类,可以说是聚类算法里面最基本的两种方法(wiki的cl ...
- 聚类方法:DBSCAN算法研究(1)--DBSCAN原理、流程、参数设置、优缺点以及算法
DBSCAN聚类算法三部分: 1. DBSCAN原理.流程.参数设置.优缺点以及算法: http://blog.csdn.net/zhouxianen1987/article/detai ...
- 【图像分割】基于matlab萤火虫算法图像聚类分割【含Matlab源码 2106期】
⛄一.萤火虫算法图像聚类分割简介 1 萤火虫算法的基本原理 1.1 萤火虫算法的数学表述 根据萤火虫算法的仿生原理,萤火虫算法的数学描述如下,萤火虫个体的相对发光强度可由式(2)确定 式中:rij为萤 ...
- kmeans算法_KMeans聚类算法详解
1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支持向量机,集成算法Ad ...
- PCL 点云分割与分类 Segmentation RANSAC随机采样一致性 平面模型分割 欧氏距离分割 区域聚类分割算法 最小分割算法 超体聚类 渐进式形态学滤波器
点云分割 博文末尾支持二维码赞赏哦 _ 点云分割是根据空间,几何和纹理等特征对点云进行划分, 使得同一划分内的点云拥有相似的特征,点云的有效分割往往是许多应用的前提, 例如逆向工作,CAD领域对零件的 ...
最新文章
- 河池学院计算机与信息工程学院官网 领导,关于成立我院宣传工作领导小组的方案...
- [转]浅谈OCR之Tesseract
- ibatis代码生成器
- 【采用】信用风险评分卡系列之数据处理
- 【SMTP 补录 Apache服务】
- 易写易库(EXEK)玩“花”儿之三:命令有图标支持库,附图
- 小试牛刀:文本处理工具之grep、egrep详解
- 携程到底有没有杀熟?
- 主动风险管理:警报如洪水怎么破?
- centos从安装到环境配置
- 《Effective Java》第5条:避免创建不必要的对象
- 推荐系统概述——《ML算法原理和实践》学习笔记
- 谷歌验证码 ReCaptcha 破解
- 椭圆曲线形式下的Pedersen commitment——vector commitment和polynomial commitment
- 云知声-AI离线语音识别芯片模块系列方案介绍
- 解决:idea打开项目后卡住,界面一直白色
- 哔哩哔哩20校招算法笔试题(2019.8.20)第二道编程题 AC
- 《变形金刚ONLINE》策划案
- 蹲草丛-dfs或者bfs找最小的连着草丛i
- 大麦票夹:从工具到服务的技术演进之路