21xrx.com
2024-05-20 20:36:58 Monday
登录
文章检索 我的文章 写文章
K-means算法C代码实现
2023-10-09 08:54:58 深夜i     --     --
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算法的原理和实现方式,并在实际应用中对数据进行聚类分析。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复