资源简介
k-means多维聚类c++实现
代码片段和文件信息
#include
#include
#include
#include
#include
using namespace std;
// 数据对象,size为维度
struct Vector
{
double* coords; // 所有维度的数值
int size;//数据维度
Vector() : coords(0) size(0) {}
Vector(int d) { create(d); }
// 创建维度为d的数据,并将各维度初始化为0
void create(int d)
{
size = d;
coords = new double[size];//size维,每一维用double类型表示值
for (int i=0; i coords[i] = 0.0;
}
// 复制一个数据
void copy(const Vector& other)
{
if (size == 0) // 如果原来没有数据,创建之
create(other.size);
for (int i=0; i coords[i] = other.coords[i];
}
// 将另一个数据的各个维度加在自身的维度上
void add(const Vector& other)
{
for (int i=0; i coords[i] += other.coords[i];
}
// 释放数值的空间
~Vector()
{
if(coords)
delete[] coords;
size = 0;
}
};
// 聚类结构
struct Cluster
{
Vector center; // 中心/引力数据对象
int* member; // 该聚类中各个数据的索引
int memberNum; // 数据的数量
};
// KMeans算法类
class KMeans
{
private:
int num; // 输入数据的数量
int dimen; // 数据的维数
int clusterNum; // 数据的聚类数
Vector* observations; // 所有数据存放在这个数组中
Cluster* clusters; // 聚类数组
int passNum; // 迭代的趟数
public:
// 初始化参数和动态分配内存
KMeans(int n int d int k Vector* ob)
: num(n)
dimen(d)
clusterNum(k)
observations(ob)
clusters(new Cluster[k])
{
for (int j=0; j clusters[j].member = new int[n];//这里为什么每个聚类的数据索引被分配n个指针而不是Cluster.memberNum个?
}
// 释放内存
~KMeans()
{
for (int k=0; k delete [] clusters[k].member;
delete [] clusters;
}
void initClusters()
{
// 由于初始数据中心是任意的,
// 所以直接把前个数据作为NumClusters个聚类的数据中心
for (int i=0; i {
clusters[i].member[0] = i; // 记录这个数据的索引到第i个聚类中
clusters[i].center.copy(observations[i]); // 把这个数据作为数据中心
}
}
void run()
{
bool converged = false; // 是否收敛
passNum = 0;
while (!converged && passNum < 999) // 如果没有收敛,则再次迭代
// 正常情况下总是会收敛,passNum < 999是防万一
{
distribute(); // 将数据分配到聚中心最近的聚类
converged = recalculateCenters(); // 计算新的聚类中心,如果计算结果和上次相同,认为已经收敛
passNum++;
}
}
void distribute()
{
// 将上次的记录的该聚类中的数据数量清0,重新开始分配数据
for(int k=0; k getCluster(k).memberNum = 0;
// 找出每个数据的最近聚类数据中心,并将该数据分配到该聚类
for(int i=0; i {
Cluster& cluster = getCluster(closestCluster(i)); // 找出最接近的其中心的聚类
int memID = cluster.memberNum; // memberNum是当前记录的数据数量,也是新加入数据在member数组中的位置
cluster.member[memID] = i; // 将数据索引加入Member数组
cluster.memberNum++; // 聚类中的数据数量加1
}
}
int closestCluster(int id)
{
int clusterID = 0; // 暂时假定索引为id的数据最接近第一个聚类
d
- 上一篇:vc++ opengl 下雪场景实现
- 下一篇:将数字转换为大写汉字的c++程序
评论
共有 条评论