21xrx.com
2025-04-15 04:07:33 Tuesday
文章检索 我的文章 写文章
K-means算法C代码实现
2023-10-09 08:54:58 深夜i     8     0
means 算法 C代码实现 聚类 数据集

K-means算法是一种经典的聚类算法,它能够将数据集分为指定数量的簇。本文将介绍使用C语言实现K-means算法的代码。

K-means算法的核心思想是将数据集中的所有点划分为K个簇,使得同一个簇内的点之间的相似度最高,而不同簇之间的相似度最低。算法的具体步骤如下:

1. 随机初始化K个簇的中心点位置。

2. 将每个数据点分配给距离它最近的簇中心点。

3. 根据每个簇中的数据点重新计算簇中心点的位置。

4. 重复步骤2和步骤3,直到簇中心点不再变化或者达到最大迭代次数。

下面是使用C语言实现K-means算法的代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define DATA_POINTS 100
#define K_CLUSTERS 3
#define MAX_ITERATIONS 100
typedef struct
  float x;
  float y;
Point;
typedef struct
  Point centroid;
  int num_points;
Cluster;
// 计算两个点之间的距离
float calculate_distance(Point point1, Point point2) {
  return sqrt(pow(point2.x - point1.x, 2) + pow(point2.y - point1.y, 2));
}
// 根据当前点和簇中心点之间的距离,得到最近簇的索引
int get_nearest_cluster(Point point, Cluster clusters[K_CLUSTERS]) {
  int index = 0;
  float min_distance = calculate_distance(point, clusters[0].centroid);
  for (int i = 1; i < K_CLUSTERS; i++) {
    float distance = calculate_distance(point, clusters[i].centroid);
    if (distance < min_distance)
      min_distance = distance;
      index = i;
    
  }
  return index;
}
// 更新每个簇的中心点位置
void update_cluster_centroids(Point data_points[DATA_POINTS], Cluster clusters[K_CLUSTERS]) {
  for (int i = 0; i < K_CLUSTERS; i++) {
    clusters[i].centroid.x = 0;
    clusters[i].centroid.y = 0;
    clusters[i].num_points = 0;
  }
  for (int i = 0; i < DATA_POINTS; i++) {
    int cluster_index = data_points[i].cluster;
    clusters[cluster_index].centroid.x += data_points[i].x;
    clusters[cluster_index].centroid.y += data_points[i].y;
    clusters[cluster_index].num_points++;
  }
  for (int i = 0; i < K_CLUSTERS; i++) {
    if (clusters[i].num_points > 0) {
      clusters[i].centroid.x /= clusters[i].num_points;
      clusters[i].centroid.y /= clusters[i].num_points;
    }
  }
}
int main() {
  Point data_points[DATA_POINTS];
  Cluster clusters[K_CLUSTERS];
  // 初始化数据点的位置
  for (int i = 0; i < DATA_POINTS; i++) {
    data_points[i].x = ((float) rand()) / RAND_MAX;
    data_points[i].y = ((float) rand()) / RAND_MAX;
  }
  // 随机选取K个簇的初始位置
  for (int i = 0; i < K_CLUSTERS; i++) {
    clusters[i].centroid.x = ((float) rand()) / RAND_MAX;
    clusters[i].centroid.y = ((float) rand()) / RAND_MAX;
    clusters[i].num_points = 0;
  }
  // 迭代优化簇的位置,直到达到最大迭代次数或者簇的位置不再变化
  for (int iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
    // 将每个数据点分配给最近的簇
    for (int i = 0; i < DATA_POINTS; i++) {
      int nearest_cluster = get_nearest_cluster(data_points[i], clusters);
      data_points[i].cluster = nearest_cluster;
    }
    // 更新每个簇的中心点位置
    update_cluster_centroids(data_points, clusters);
  }
  // 打印每个簇最终的中心点位置
  for (int i = 0; i < K_CLUSTERS; i++) {
    printf("Cluster %d centroid: (%f, %f)\n", i+1, clusters[i].centroid.x, clusters[i].centroid.y);
  }
  return 0;
}

上述代码实现了K-means算法的核心逻辑,通过迭代的方式将数据点分配给最近的簇,并更新簇的中心点位置,最终得到每个簇的中心点位置。通过对随机生成的数据点进行聚类,可以观察到每个簇的中心点位置。

需要注意的是,此处为了简化代码,省略了对输入数据的读取和对结果的输出。实际使用中,可以根据具体需求进行适当的修改。

总结起来,通过上述C语言的实现,我们可以更好地理解K-means算法的原理和实现方式,并在实际应用中对数据进行聚类分析。

  
  

评论区

    相似文章
请求出错了