聚类算法–近邻聚类算法(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++实现)相关推荐

  1. java实现近邻聚类算法,近邻传播聚类算法 - osc_t74tdxrl的个人空间 - OSCHINA - 中文开源技术交流社区...

    近邻传播聚类算法 1.算法简介 AP(Affinity Propagation)通常被翻译为近邻传播算法或者仿射传播算法,是在2007年的Science杂志上提出的一种新的聚类算法.AP算法的基本思想 ...

  2. python音频聚类_Python实现聚类算法AP

    1.算法简介 AP(Affinity Propagation)通常被翻译为近邻传播算法或者亲和力传播算法,是在2007年的Science杂志上提出的一种新的聚类算法.AP算法的基本思想是将全部数据点都 ...

  3. 机器学习算法之 K-means、层次聚类,谱聚类

    k-means 和层次聚类都属于划分聚类,实际中最常用的是k-means,k-means效果不好的情况下才会采用其他聚类 K-means算法 K-means算法,也称为K-平均或者K-均值,是一种使用 ...

  4. 聚类方法:DBSCAN算法研究

    DBSCAN聚类算法三部分: 1.        DBSCAN原理.流程.参数设置.优缺点以及算法: http://blog.csdn.net/zhouxianen1987/article/detai ...

  5. 聚类算法实践——谱聚类、Chameleon聚类

    转载自:http://www.itongji.cn/article/0R52D42013.html 上一篇文章里说到的层次聚类和K-means聚类,可以说是聚类算法里面最基本的两种方法(wiki的cl ...

  6. 聚类方法:DBSCAN算法研究(1)--DBSCAN原理、流程、参数设置、优缺点以及算法

    DBSCAN聚类算法三部分: 1.        DBSCAN原理.流程.参数设置.优缺点以及算法: http://blog.csdn.net/zhouxianen1987/article/detai ...

  7. 【图像分割】基于matlab萤火虫算法图像聚类分割【含Matlab源码 2106期】

    ⛄一.萤火虫算法图像聚类分割简介 1 萤火虫算法的基本原理 1.1 萤火虫算法的数学表述 根据萤火虫算法的仿生原理,萤火虫算法的数学描述如下,萤火虫个体的相对发光强度可由式(2)确定 式中:rij为萤 ...

  8. kmeans算法_KMeans聚类算法详解

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支持向量机,集成算法Ad ...

  9. PCL 点云分割与分类 Segmentation RANSAC随机采样一致性 平面模型分割 欧氏距离分割 区域聚类分割算法 最小分割算法 超体聚类 渐进式形态学滤波器

    点云分割 博文末尾支持二维码赞赏哦 _ 点云分割是根据空间,几何和纹理等特征对点云进行划分, 使得同一划分内的点云拥有相似的特征,点云的有效分割往往是许多应用的前提, 例如逆向工作,CAD领域对零件的 ...

最新文章

  1. 河池学院计算机与信息工程学院官网 领导,关于成立我院宣传工作领导小组的方案...
  2. [转]浅谈OCR之Tesseract
  3. ibatis代码生成器
  4. 【采用】信用风险评分卡系列之数据处理
  5. 【SMTP 补录 Apache服务】
  6. 易写易库(EXEK)玩“花”儿之三:命令有图标支持库,附图
  7. 小试牛刀:文本处理工具之grep、egrep详解
  8. 携程到底有没有杀熟?
  9. 主动风险管理:警报如洪水怎么破?
  10. centos从安装到环境配置
  11. 《Effective Java》第5条:避免创建不必要的对象
  12. 推荐系统概述——《ML算法原理和实践》学习笔记
  13. 谷歌验证码 ReCaptcha 破解
  14. 椭圆曲线形式下的Pedersen commitment——vector commitment和polynomial commitment
  15. 云知声-AI离线语音识别芯片模块系列方案介绍
  16. 解决:idea打开项目后卡住,界面一直白色
  17. 哔哩哔哩20校招算法笔试题(2019.8.20)第二道编程题 AC
  18. 《变形金刚ONLINE》策划案
  19. 蹲草丛-dfs或者bfs找最小的连着草丛i
  20. 大麦票夹:从工具到服务的技术演进之路

热门文章

  1. 女性英文名字大全,还有来历、释义
  2. CZXX 1+X测试
  3. 个人电脑链接本地/云服务器
  4. 戴尔服务器R730XD增加万兆光卡后风扇满速运转解决办法
  5. 揭秘你代理商做不起来货卖不出去的原因,探讨其背后的商业逻辑
  6. Java校验银行卡号的合法性以及根据银行卡号校验银行卡所属的银行名称是否一样?
  7. aix系统怎么修改服务器时间同步,AIX时间同步
  8. Linux下通过USB连接并利用手机拨号上网
  9. 快速了解小程序的云开发
  10. heapdump定位内存泄露