k-means算法c++实现

news2025/2/22 19:40:32

 计算数据集中的元素与各个簇的中心的距离,将它赋给最近的簇,然后重新计算每个簇的平均值,再将元素按离平均值点最近的原则重新分配直到没有出现重新分配

该算法要事先给出k的值,即划分为几个簇。

vector<int> datoclu(data.size(), -1);用这个来标记每个数据在哪个簇中。

#include <fstream>
#include <sstream>
#include <vector>
#include <iostream>

using namespace std;

struct Point
{
    double x;
    double y;
};


double distance(const Point& a, const Point& b)
{
    return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}

vector<int> KMeans(vector<Point>& data, int k, int maxIterations)
{
    vector<Point> centroids(k);
    for (int i = 0; i < k; i++)          
    {
        centroids[i] = data[rand() % data.size()];      //随机选择k个类聚中心。0到(data.size()-1)
    }

    vector<int> datoclu(data.size(), -1);           //每个数据属于哪个簇
    bool flag = 0;
    while (!flag && maxIterations)
    {
        flag = 1;
        for (int i = 0; i < data.size(); i++)
        {
            double minDis = numeric_limits<double>::max();
            int index = -1;
            for (int j = 0; j < centroids.size(); j++)
            {
                double dis = distance(data[i], centroids[j]);
                if (dis < minDis)
                {
                    minDis = dis;
                    index = j;
                }
            }
            if (datoclu[i] != index)                //记录每个数据属于的聚类中心
            {
                datoclu[i] = index;
                flag = 0;
            }
        }

        vector<Point> newClu(k);
        vector<int> num(k, 0);

        //计算每个簇平均值点
        for (int i = 0; i < data.size(); i++)
        {
            newClu[datoclu[i]].x += data[i].x;
            newClu[datoclu[i]].y += data[i].y;
            num[datoclu[i]]++;
            
        }
        for (int i = 0; i < k; i++)
        {
            newClu[i].x /= num[i];
            newClu[i].y /= num[i];
        }
        centroids = newClu;
        maxIterations--;
    }
    return datoclu;
}
vector<Point> ReadData(string filename)
{
    vector<Point> data;
    ifstream file(filename);
    if (file.is_open())
    {
        string line;
        while (getline(file, line))
        {
            istringstream iss(line);
            double x, y;
            string token;
            Point point;
            if (getline(iss, token, ',') && istringstream(token) >> point.x &&
                getline(iss, token, ',') && istringstream(token) >> point.y) {
                data.push_back(point);
            }
        }
    }
    else
    {
        cout << "open fail";
    }
    file.close();
    return data;
}

int main()
{
    vector<Point> dataset = ReadData("data.txt");
    vector<int> clusters;
    int k, maxIterations;
    cout << "输入簇的个数和最大迭代次数"<<endl;
    cin >> k >> maxIterations;
    clusters= KMeans(dataset, k, maxIterations);
    vector <vector<int>> index(k);
   
    for (int j = 0; j < k; j++)
    {
        for (int i = 0; i < clusters.size(); i++)
        {
            if (clusters[i] == j)
            {
                 index[j].push_back(i);
            }
        }
    }
    for (int i = 0; i < index.size(); i++)
    {
        cout << "{";
        for (int j = 0; j < index[i].size(); j++)
        {
            
            cout << index[i][j]+1;
            if (j != index[i].size() - 1)
            {
                cout << ",";
            }
        }
        cout << "}";
    }
}    

数据集

1.0, 1.0 
2.0, 1.0 
1.0, 2.0  
2.0, 2.0  
4.0, 3.0  
5.0, 3.0  
4.0, 4.0  
5.0,4.0

运行结果 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1169626.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JDBC数据库连接---附通用的CRUD类

文章目录 JDBC数据库连接1 导包2 编写配置文件3 编写连接数据库代码4 测试工具类5 附加1 通用的CRUD类2 测试CURD类3 测试 JDBC数据库连接 本篇文章以 MySQL 数据库为例&#xff0c;若要切换其他数据库&#xff0c;只需修改 resource文件夹中的 jdbc.properties 配置文件即可。…

《实战:如何搭建一个完整的 Vue2.0 项目》- 7、Vue2.x 项目 webpack 4 升级 5(半自动升级)

1.自动升级 先全局安装升级插件 npm i npm-check npm-check-updates -g检查依赖 npm-check更新检查后的依赖并展示版本号&#xff0c;此时 package.json还没有更新 npm-check-updates升级 package.json&#xff0c;下图显示更新版本&#xff0c;此时 package.json文件已变更…

客服管理者如何调动客服人员的积极性?

客户是企业的财富&#xff0c;良好的客户服务体验可以有效地促进企业的销售和声誉&#xff0c;因此&#xff0c;客服工作显得尤为重要。而客服人员的积极性直接影响了整个客服部门的质量和效率。如何调动客服人员的积极性&#xff0c;成为了每个客服管理者都需要面对的难题。本…

Mendix 创客访谈录|质量部门开发应用程序自主可控

本期创客 我们是来自于西门子成都工厂质量部的 Mendix “草台班子” 创客访谈 在使用Mendix低代码平台开发应用软件前&#xff0c;你和你的部门/团队主要应用什么开发工具&#xff1f; 我们质量部属于OT&#xff08;运营技术&#xff09;部门, 一般是使用一些IT团队提供的功能单…

Mongoose 开源库--Filesystem(文件系统)使用笔记

一、相关API Mongoose 开源库中也包含 文件系统 相关的 API&#xff0c;如下&#xff1a; 文件虚拟层&#xff1a; struct mg_fs {int (*st)(const char *path, size_t *size, time_t *mtime); // stat filevoid (*ls)(const char *path, void (*fn)(const char *, void *), v…

结合选择MES管理系统供应商的关键因素进行深入探讨

在现代化的制造业中&#xff0c;MES管理系统已经成为了提高生产效率、降低成本、增强产品质量的重要工具。然而&#xff0c;选择一个合适的MES管理系统系统供应商并不是一件轻而易举的事。它需要对多个因素进行深入的权衡和考虑。结合上述的关键挑选因素&#xff0c;我们进一步…

C++二叉搜索树BinarySearchTree

一、介绍 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 1.若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 2.若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 3.它的左右…

C#,数值计算——积分方程与逆理论,构造n点等间隔求积的权重的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// 构造n点等间隔求积的权重 /// Constructs weights for the n-point equal-interval quadrature /// from O to(n-1)h of a function f(x) times an arbitrary /// (pos…

Parasoft C/C++test:汽车网络安全ISO 21434最佳实践

为什么汽车网络安全很重要Why Automotive Cybersecurity Is Important 许多汽车公司向电子道路车辆的转变从根本上改变了整个行业&#xff0c;提高了汽车的互联性和智能性。随着电子汽车变得更加互联和智能&#xff0c;它们也越来越依赖软件来实现车辆操作&#xff0c;驱动更多…

Netty实战专栏 | JavaIO演进之路

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Netty实战专栏 ✨特色专栏&#xff1a…

性能优于BERT的FLAIR:一篇文章入门Flair模型

文章目录 What is FLAIR&#xff1f;FLAIR ModelContextual String Embedding for Sequence Labelingexample FLAIR Application AreaSentiment AnalysisNamed Entity RecognitionText Classification FLAIR一、什么是FLAIR&#xff1f;二、FLAIR Library的优势是什么&#xff…

Linux flock和fcntl函数详解

文章目录 flock函数描述返回值和错误码笔记 fcntl函数描述复制文件描述符文件描述标志文件状态标志 咨询锁强制锁管理信号租赁文件和目录变更通知改变管道容量 返回值错误备注遗留问题 flock函数 主要功能是在已打开的文件应用或者删除共享锁或者独占锁。sys/file.h声明了这个…

时间序列聚类的直观方法

一、介绍 我们将使用轮廓分数和一些距离度量来执行时间序列聚类实验&#xff0c;同时利用直观的可视化&#xff0c;让我们看看下面的时间序列&#xff1a; 这些可以被视为具有正弦、余弦、方波和锯齿波的四种不同的周期性时间序列 如果我们添加随机噪声和距原点的距离来沿 y 轴…

苹果加大对印度的扶持,提高在其生产iphone的比重

KlipC报道&#xff1a;跟踪苹果产业链&#xff0c;有分析师预计2023年全球约12%-14%的iphone在印度生产&#xff0c;预计2024年&#xff0c;印度将生产20%-25%的iphone。 KlipC的合伙人Andi D表示&#xff1a;“近年来随着苹果对中国的以来&#xff0c;印度已经成为高科技制造和…

Netty实战专栏 | BIO详解

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Netty实战专栏 ✨特色专栏&#xff1a…

ESP32 for Arduino 分区信息

忘记过去&#xff0c;超越自己 ❤️ 博客主页 单片机菜鸟哥&#xff0c;一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-11-04❤️❤️ 本篇更新记录 2023-11-04❤️&#x1f389; 欢迎关注 &#x1f50e;点赞 &#x1f44d;收藏 ⭐️留言&#x1f4dd;&#x1f64f;…

“线性函数”和“非线性函数”是什么?

总是会把“线性函数”和“非线性函数”与“连续的数据类型”与“非连续的数据类型”混淆&#xff0c;特此记录 一、线性函数&#xff1a; 一个函数 f 是线性的&#xff0c;如果对于任何两个输入 x1​ 和 x2​ 和任何两个常数 a 和 b&#xff0c;下列等式成立&#xff1a; 例如…

BIOS开发笔记 - HDA Audio

在PC中,音频输出是一个重要的功能之一,目前大多数采用的是英特尔高清晰音效(英语:Intel High Definition Audio,简称为HD Audio或IHD)方案,它是由Intel于2004年所提出的音效技术,能够展现高清晰度的音质效果,且能进行多声道的播放,在音质(音效质量)上超越过去的其他…

Ubuntu18.04 下PCL的卸载与安装

目录 一、卸载有问题的PCL1.7 二、编译&&安装PCL1.8.1 2.1、安装PCL依赖 2.2、编译VTK 2.3、编译PCL源码 三、 总结 写这篇博客时&#xff0c;本文方法已经在笔记本Ubuntu和VM虚拟机成功安装PCL1.8.1&#xff0c;并且通过测试。 下文方法同样适用于ubuntu18.04。…