层次汇合聚类(Hierarchical Agglomerative Clustering,HAC)
算法如下:

相关链接:
层次聚类算法原理及实现

学习笔记:
先附上上一段链接中的代码:

// HAC_learning.cpp: 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
using namespace std;
const int iniClusNum = 12;
const int stopNum = 3;class Point
{public:double x;double y;int NumPBelong;Point(){x = 0;y = 0;NumPBelong = -1;}Point(double x1, double y1, int f = -1) :x(x1), y(y1), NumPBelong(f) {}const Point& operator=(const Point& p){x = p.x;y = p.y;NumPBelong = p.NumPBelong;return *this;}
};class ManagerP
{public:double getDistance(const Point& p1, const Point& p2){return sqrt(pow((p1.x - p2.x), 2) + pow((p1.y - p2.y), 2));}Point getMean(const Point& p1, const Point& p2){Point p;p.x = (p1.x + p2.x) / 2;p.y = (p1.y + p2.y) / 2;return p;}
};class ManagerC
{public:Point Cluster[iniClusNum];vector<int> ClusterLast[iniClusNum];bool isIndexClose[iniClusNum];bool isIndexClose2[iniClusNum];void initCluster()//use txt to init, import txt{ifstream  myfile("point.txt");if (!myfile){cout << "cannot open file.";   return;}Point p;int x, y;int i = 0;while (!myfile.eof()){myfile >> x >> y;p.x = x;p.y = y;Cluster[i] = p;i++;}myfile.close();}void initIndexClose(){for (int i = 0; i<iniClusNum; i++){isIndexClose[i] = false;isIndexClose2[i] = false;}}void print(){for (int i = 0; i<iniClusNum; i++){if (ClusterLast[i].empty()){continue;}cout << "cluster " << i + 1 << endl;vector<int>::iterator ite = ClusterLast[i].begin();for (; ite != ClusterLast[i].end(); ite++){cout << *ite << "\t";}cout << endl;}cout << endl;}void ClusterAlgo()//use minheap to realize, to optimize{int ClustNum = iniClusNum;int clus_index = 0;while (ClustNum>stopNum){double min = INT_MAX;int x = -1, y = -1;ManagerP mp;for (int i = 0; i<iniClusNum; i++){if (isIndexClose[i]){continue;}for (int j = i + 1; j<iniClusNum; j++){if (isIndexClose[j]){continue;}double new_d = mp.getDistance(Cluster[i], Cluster[j]);if (new_d < min){min = new_d;x = i; y = j;}}}if (x == -1 || y == -1){break;}Point p = mp.getMean(Cluster[x], Cluster[y]);//x<y store the resultif (Cluster[x].NumPBelong == -1 && Cluster[y].NumPBelong == -1){cout << "a0" << endl;ClusterLast[clus_index].push_back(x);//xchange to p, y closeClusterLast[clus_index].push_back(y);p.NumPBelong = clus_index;isIndexClose[y] = true;//y is closedCluster[x] = p;//new p is openisIndexClose[x] = false;isIndexClose2[x] = true;isIndexClose2[y] = true;clus_index++;}else if (Cluster[x].NumPBelong == -1 && Cluster[y].NumPBelong != -1)//already exists one cluster{cout << "a1" << endl;ClusterLast[Cluster[y].NumPBelong].push_back(x);isIndexClose[x] = true;//x is closedp.NumPBelong = Cluster[y].NumPBelong;Cluster[y] = p;//new p is openisIndexClose2[x] = true;}else if (Cluster[x].NumPBelong != -1 && Cluster[y].NumPBelong == -1){cout << "a2" << endl;ClusterLast[Cluster[x].NumPBelong].push_back(y);isIndexClose[y] = true;//y is closedp.NumPBelong = Cluster[x].NumPBelong;Cluster[x] = p;//new p is openisIndexClose2[y] = true;}else if (Cluster[x].NumPBelong != -1 && Cluster[y].NumPBelong != -1)//both are clusteroid{cout << "a3" << endl;vector<int>::iterator ite = ClusterLast[Cluster[y].NumPBelong].begin();//put y's node in xfor (; ite != ClusterLast[Cluster[y].NumPBelong].end(); ite++){ClusterLast[Cluster[x].NumPBelong].push_back(*ite);}ClusterLast[Cluster[y].NumPBelong].clear();isIndexClose[y] = true;//y is closedp.NumPBelong = Cluster[x].NumPBelong;Cluster[x] = p;//new p is open}ClustNum--;}int total_size = 0;for (int i = 0; i<stopNum; i++){total_size += ClusterLast[i].size();}if (total_size<iniClusNum){int j = 0;for (int i = 0; i<iniClusNum; i++){if (isIndexClose2[i] == false){ClusterLast[stopNum - 1 - j].push_back(i);j++;}}}}};int main()
{ManagerC M;M.initCluster();M.initIndexClose();M.ClusterAlgo();M.print();system("pause");
}

其中,
point.txt:

4 10
4 8
7 10
6 8
3 4
2 2
5 2
9 3
10 5
11 4
12 3
12 6

运行结果:

草图:

代码理解:
定义类point,含有x,y(坐标)及NumPBelong(类别)
M.initCluster();输入数据
M.initIndexClose();开启所有点(设为false)
M.ClusterAlgo();HAC聚类
M.print();打印聚类结果

详细理解M.ClusterAlgo();

设定预期分类数stopNum,令实际分类数初始值为输入数据数(每个数据自成一类)
当(实际分类数>预期分类数stopNum)时
{clus_index=0;在x,y的isIndexClose值都不为true(关)的条件下(不为中心点/没有改变过)找出距离最小的两个点x,y并计算他们的距离min如果所有的点的isIndexClose值都为true(关)跳出循环//计算x,y的中点pa0:如果x,y都不是某类的中心点将x,y分入第clus_index类关闭y(isIndexClose=true)(y不再是某类中心点)把x,y的中点设为x,并令这个新的x为此类的中心点打开x(isIndexClose=true)(x为此类中心点)标记x,y(isIndexClose2= true;)a1:如果x不是某类中心点,y是某类中心点将x放入y所在的类别中关闭x把x,y的中点设为y标记xa2:如果x是某类中心点,y不是某类中心点将y放入x所在的类别中关闭y把x,y的中点设为x标记ya3:如果x,y都是中心点把y所在类别的所有点移入x所在类别中关闭y把x,y的中点设为x
实际分类数-1
}
计算所有已分类类别中数据的总数total_size
如果已分类数据总数total_size<原始输入数据总数iniClusNum(有数据未分类)
{对每一个数进行检查,将所有未标记数(isIndexClose2 == false)平均分给各个类
}

【web搜索】学习笔记-层次汇合聚类HAC算法相关推荐

  1. ELK搜索学习笔记--Day1

    ELK搜索学习笔记–Day1 1. 课程简介 1.1 课程内容 ELK是包含但不限于Elasticsearch(简称es).Logstash.Kibana 三个开源软件的组成的一个整体.这三个软件合成 ...

  2. 基于Solr的空间搜索学习笔记

    基于Solr的空间搜索学习笔记 在Solr中基于空间地址查询主要围绕2个概念实现: (1) Cartesian Tiers 笛卡尔层 Cartesian Tiers是通过将一个平面地图的根据设定的层次 ...

  3. Java web与web gis学习笔记(二)——百度地图API调用

    系列链接: Java web与web gis学习笔记(一)--Tomcat环境搭建 Java web与web gis学习笔记(二)--百度地图API调用 JavaWeb和WebGIS学习笔记(三)-- ...

  4. web安全学习笔记--sql语句(sql注入基础上)

    一.基础知和表内操作语法 1.sql语句对大小写不敏感!!! SELECT - 从数据库表中获取数据:select * from (columns/tables/databases); UPDATE ...

  5. web前端学习笔记(最新)

    web前端学习笔记 大家好,我是链表哥,新的学期,新的学习,我会为您展示我的学习进程. 一:什么是WEB前端? 所谓的Web前端指的是用户所能接触到的,并服务于用户的前沿端口,经我们程序员编辑修饰后展 ...

  6. Web Components 学习笔记一: Web Components是什么?解决了什么问题?

    公众号:妙蛙种子前端 文章原文地址:Web Components笔记一: Web Components是什么?解决了什么问题? | 妙蛙种子 - 记录WEB前端技术学习成长过程的博客 Web Comp ...

  7. 深度学习笔记(10) 优化算法(二)

    深度学习笔记(10) 优化算法(二) 1. Adam 优化算法 2. 学习率衰减 3. 局部最优的问题 1. Adam 优化算法 Adam代表的是 Adaptive Moment Estimation ...

  8. 深度学习笔记(9) 优化算法(一)

    深度学习笔记(9) 优化算法(一) 1. Mini-batch 梯度下降 2. 指数加权平均数 3. 动量梯度下降法 4. 均方根反向传播 1. Mini-batch 梯度下降 把训练样本放大巨大的矩 ...

  9. 【C++ Primer 学习笔记】: 容器和算法之【泛型算法】

    本系列博客主要是在学习 C++ Primer 时的一些总结和笔记. [C++ Primer 学习笔记]: 容器和算法之[泛型算法] 本文地址:http://blog.csdn.net/shanglia ...

最新文章

  1. MultiBinding的StringFormat参数问题
  2. 【错误记录】Windows 系统 bat 脚本报错 ( 使用 pause 拦截窗口自动关闭 | 方便查看错误 )
  3. 编译arm平台的ethtool
  4. tp框架 db::name_玩! 框架:为什么我会爱上它
  5. 玩家在RTX 3090显卡中发现了指套
  6. 【清北学堂】广州OI学习游记
  7. Jstatd命令 Java Statistics Monitoring Daemon
  8. OpenShift 4.3 - 基于虚拟机的BareMetal离线安装(7-9)
  9. python 多次匹配_Python学习记录14
  10. VSCode:vscode设置侧边资源管理器文字大小
  11. dx绘制2d图像_【3D建模】聊聊2D动画软件
  12. java模拟面试题目_JAVA模拟面试题库
  13. 一个不错的Fortran教程
  14. 财务分析报表APP的功能优势
  15. 3500振动监测系统培训总结
  16. mysql 回滚 大小设置_MySQL事物提交与回滚
  17. LC152---乘积最大子数组
  18. 蓝牙通信工作流程讲解
  19. 【洛谷】P5960 【模板】差分约束算法
  20. 催眠曲用计算机怎么弹,在电脑中巧播“催眠曲”

热门文章

  1. android代码实现手机加速功能吗,详解Android开发中硬件加速支持的使用方法
  2. 2022年我在梦想清单里又加了3条
  3. 分布式 b2b b2c o2o电子商务 云平台
  4. 解决git pull时出现的几个问题
  5. 烂泥:mysql5.5主从同步复制配置
  6. 北斗时钟服务器(NTP服务器)让高考时间更加精准
  7. 什么是Java的永久代(PermGen)内存泄漏
  8. tensorflw视频
  9. 编码与DNA存储——DNA码的构造
  10. [USACO13NOV]挤奶牛Crowded Cows(洛谷 P3088)