首页 > 编程语言 >k_means算法

k_means算法

时间:2024-02-01 09:59:52浏览次数:29  
标签:dist means int centroids dataset ++ 算法 质心

C语言代码

#include <iostream>
using namespace std;

// 定义点的结构体
struct point {
    double x;  // 点的x坐标
    double y;  // 点的y坐标
    int centroid;  // 点所属的质心
};

// 定义计算两点之间距离的函数
double dist(struct point a, struct point b) {
    return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}

/// <summary>
/// 定义kmeans算法函数
/// </summary>
/// <param name="dataset">需要分类的数据点</param>
/// <param name="N">定义数据点的数量</param>
/// <param name="K">定义质心的数量</param>
/// <param name="centroids">k个质心坐标</param>
/// <param name="iter">迭代次数</param>
void kmeans(point* dataset, int N, int K, point* centroids, int* iter) {
    // 初始化质心为数据集中的前k个元素
    for (int i = 0; i < K; i++) {
        centroids[i] = dataset[i];
    }

    // 重复直到收敛
    while (1) {
        int changed = 0;  // 标记是否有点的质心发生改变

        // 将每个点分配给最近的质心
        for (int i = 0; i < N; i++) {
            int closest = 0;  // 最近的质心
            double closest_dist = dist(dataset[i], centroids[0]);  // 最近的距离
            for (int j = 1; j < K; j++) {
                double dist_j = dist(dataset[i], centroids[j]);  // 计算到质心j的距离
                if (dist_j < closest_dist) {  // 如果到质心j的距离小于当前最近的距离
                    closest = j;  // 更新最近的质心
                    closest_dist = dist_j;  // 更新最近的距离
                }
            }
            if (dataset[i].centroid != closest) {  // 如果点的质心发生改变
                dataset[i].centroid = closest;  // 更新点的质心
                changed = 1;  // 标记有点的质心发生改变
            }
        }

        // 更新质心
        for (int i = 0; i < K; i++) {
            double sum_x = 0, sum_y = 0;  // 质心的x坐标和y坐标的和
            int count = 0;  // 属于该质心的点的数量
            for (int j = 0; j < N; j++) {
                if (dataset[j].centroid == i) {  // 如果点属于该质心
                    sum_x += dataset[j].x;  // 累加x坐标
                    sum_y += dataset[j].y;  // 累加y坐标
                    count++;  // 累加点的数量
                }
            }
            centroids[i].x = sum_x / count;  // 更新质心的x坐标
            centroids[i].y = sum_y / count;  // 更新质心的y坐标
        }

        if (!changed) {  // 如果没有点的质心发生改变
            break;  // 结束循环
        }
        (*iter)++;//迭代次数加一
    }
}
int main()
{
    const int N = 4;  // 定义数据集中的点的数量
    const int K = 2;  //定义质心的数量

    // 定义数据集
    struct point dataset[N] = {
        {2.0, 3.0, -1},
        {7.0, 8.0, -1},
        {9.0, 10.0, -1},
        {4.0, 5.0, -1},
    };

    // 定义质心
    struct point centroids[K];
    //定义迭代次数
    int iter = 0;
    kmeans(dataset, N, K, centroids, &iter);  // 执行kmeans算法
    //打印测试结果
    printf("迭代次数:%d\n", iter);
    for (int i = 0; i < K; i++) {
        printf("质心 %d 坐标 (%0.2f,%0.2f)\n", i, centroids[i].x, centroids[i].y);
        printf("属于该质心的点:\n");
        for (int j = 0; j < N; j++) {
            if (dataset[j].centroid == i)
                printf("(%0.1f,%0.1f)", dataset[j].x, dataset[j].y);
        }
        printf("\n\n");
    }
    return 0;
}
C语言k_means

运行结果如下

 

标签:dist,means,int,centroids,dataset,++,算法,质心
From: https://www.cnblogs.com/lizhiqiang0204/p/18000597

相关文章

  • 指针扫描型字符串算法
    【最小表示法】最小表示法循环表示:从一个位置开始向后遍历,到末尾再倒回去最前面。一个字符串(数组)一共有\(n\)个。最小表示法就是最小的循环表示。例如,31491的最小表示法是13149.如果我们用打擂台比大小的方式,因为字符串之间比较需要时间,总共是\(O(n^2)\)的,太慢......
  • 字符串算法学习笔记
    \(\text{Pt.}1\)基础一、进制哈希二、Manacher三、Trie\(\text{Pt.}2\)自动机自动机是什么?它是一个对“信息序列”进行判定的数学模型。“信息序列”可以很随意,比如一个二进制数,比如一个字符串。而“判定”也可以很随意,比如判定一个二进制数是不是奇数,判定当前字符串是......
  • CEIT算法训练-双指针部分题解(T1-3)
    AnagramSearch题意简述两个字符串\(s\)和\(t\)相似的定义为:\(s\)可以打乱之后重新排列成为\(t\)。题目给出\(a\)和\(b\),问\(a\)中有多少子串(连续的一段)与\(b\)相似。同时,\(a\)中还含有\(?\)字符,他可以等价于任何字符(可以变成任何字符)解题思路实际上,根据题......
  • 《算法导论(原书第3版)》PDF
    内容简介在有关算法的书中,有一些叙述非常严谨,但不够全面;另一些涉及了大量的题材,但又缺乏严谨性。本书将严谨性和全面性融为一体,深入讨论各类算法,并着力使这些算法的设计和分析能为各个层次的读者接受。全书各章自成体系,可以作为独立的学习单元;算法以英语和伪代码的形式描述,具备初步......
  • Python 机器学习 K-近邻算法 常用距离度量方法
    ​K-近邻(K-NearestNeighbors,KNN)算法中,选择合适的距离度量是非常重要的,因为它决定了如何计算数据点之间的“相似性”。不同的距离度量可能会导致不同的KNN模型性能。选择哪种距离度量取决于数据的类型和问题的性质。可以通过交叉验证来比较不同距离度量对模型性能的影响,以选择最......
  • 算法学习笔记(44): 二维问题小计
    首先需要理解什么是二维问题。$n$维空间体系:将元素变成$n$维空间中的点,将范围变成$n$维空间中的正交范围。二维问题就是每一个元素都可以看作一个平面上的坐标\((x,y)\)。其中一维可以是下标,时间,值,dfn,甚至是一个函数\((x,f(x))\)。经典的二维问题实际上就是矩形加,矩......
  • ICDE 2023 探索并行过滤图:革新层次聚类算法
    ICDE2023|探索并行过滤图,革新层次聚类算法机器学习中的无监督学习方法现在已经被广泛运用,特别是聚类算法被广泛运用于经济、生物以及机器视觉等多种领域之中。而聚类算法中也包含许多方向,如基于密度聚类,基于划分聚类以及基于度量聚类。传统的基于度量聚类在一个包含n个数据点......
  • 代码随想录算法训练营第八天| 344.反转字符串 541. 反转字符串II 卡码网:54.替换数字
    反转字符串编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用O(1)的额外空间解决这一问题。题目链接:344.反转字符串-力扣(LeetCode)关于是否用reverse函数解决问题:如果题目......
  • 算法题-最近公共祖先
    目录小米Git题目描述思路pyjava小米Git原题链接题目描述Git是一个常用的分布式代码管理工具,Git通过树的形式记录文件的更改历史(例如示例图),树上的每个节点表示一个版本分支,工程师经常需要找到两个分支的最近的分割点。给定一个用邻接矩阵matrix表示的树,请你找到版本v......
  • 差分算法
    差分算法差分算法可以用来维护区间的加减我们假定有一个数组\(a={1,2,3,4}\)\(b\)为数组\(a\)的差分数组。\[b_i=\begin{cases}a_i-a_{i-1}&i\in[2,n]\\a_1&i=1\end{cases}\]根据给定的数组\(a={1,2,3,4}\)我们很容易得知数组\(b={1,1,1,1}\)我......