QT+VS实现Kmeans++
1、Kmeans++的原理如下:
(1)首先选取样本中任一数据点作为第一个聚类中心;
(2)计算样本每一个数据点至现所有聚类中心的最近距离,并记录下来;
(3)逐一挑选所有数据点最近距离之中的最大值,即最远距离,最大值对应的数据点为待求聚类中心;
(4)剔除已选为聚类中心的样本点,重新计算(2)、(3)步骤,得到指定的最终的聚类中心点数。
2、实现结果如下:
注:当噪点太多时,初始K个聚类中心的计算会出现偏差,从而导致整个聚类结果出现偏差。
3、原始数据读入格式如下:
点号-X坐标-Y坐标(非此格式的数据无法正常读入,程序会报错)
4、根据Kmeans++选择k个初始聚类中心的Kmeans聚类算法整体代码如下:
//Kmeans.cpp文件
#include "Kmeans.h"Kmeans::Kmeans(QWidget *parent): QWidget(parent)
{start = false;//dd = blank;dd = to2K;ui.setupUi(this);connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(onBtReadData()));connect(ui.pushButton_2, SIGNAL(clicked()), this, SLOT(onBtCalKmeans()));connect(ui.pushButton_3, SIGNAL(clicked()), this, SLOT(onBtReadK()));
}void Kmeans::onBtReadData()
{K = ui.lineEdit->text().toInt();p.clear();//打开文件对话框QString fileName = QFileDialog::getOpenFileName(this, tr("打开"));QFile file(fileName);bool isOpen = 1;if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){isOpen = 0;QMessageBox::StandardButton btnValue = QMessageBox::information(this, tr("提示"), tr("打开失败!"));}//逐行读取文本文件QTextStream stream(&file);while (!stream.atEnd()){Pointp pt;QString str = stream.readLine();QStringList list = str.split(",");pt.no = list.at(0);pt.x = list.at(1).toDouble();pt.y = list.at(2).toDouble();p.push_back(pt);}file.close();//判断是否读取完毕if (stream.atEnd()&&isOpen){QMessageBox box;box.setText("数据读取完毕");box.exec();}
}void Kmeans::onBtReadK()
{QString fileName = QFileDialog::getOpenFileName(this, tr("打开"));QFile file(fileName);bool isOpen = 1;if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){isOpen = 0;QMessageBox::StandardButton btnValue = QMessageBox::information(this, tr("提示"), tr("打开失败!"));}QTextStream stream(&file);while (!stream.atEnd()){QString str = stream.readLine();QStringList list = str.split(",");Pointp k1;k1.no = list.at(0);k1.x = list.at(1).toDouble();k1.y = list.at(2).toDouble();k.push_back(k1);}//判断是否读取完毕if (stream.atEnd() && isOpen){QMessageBox box;box.setText("数据读取完毕");box.exec();}dd = readK;
}void Kmeans::toK()
{//随机选取k个初始聚类中心for (int i = 0; i < K; i++){Pointp k1;k1.no = i + 1;k1.x = p.at(i).x;k1.y = p.at(i).y;k.push_back(k1);}
}int Kmeans::onBtCalKmeans()
{K = ui.lineEdit->text().toInt();if (S.size()&&p.size()==S.size()){QMessageBox box;box.setText("已经计算完成");box.exec();return 0;}//if (dd == to2K)//{// toK();//}CalK();CalDis();//SCalcentroid();//用到S,得dis//CKmeans();//用到dis,得new k.int iCount = 0;while (iCount < K){if (dis.size()){for (int i = 0; i < k.size(); i++){for (int j = 0; j < dis.size(); j++){if (k.at(i).no == dis.at(j).noK){//qDebug() <<"k:" <<k.at(i).no<< k.at(i).x << k.at(i).y;//qDebug() <<"dis:" <<dis.at(i).noK.toInt()<< dis.at(j).sx << dis.at(j).sy<<endl;double detaX = k.at(i).x - dis.at(j).sx;double detaY = k.at(i).y - dis.at(j).sy;double sk = sqrt(detaX * detaX + detaY * detaY);//qDebug() << sk;if (sk == 0){iCount++;}else{CKmeans();}}}}}dis.clear();S.clear();CalDis();Calcentroid();}start = true;qDebug() << "S" << S.size();drawPoint();//drawK();QMessageBox box;box.setText("计算完成");box.exec();qDebug() << "k" << k.size();//for (int i = 0; i < S.size(); i++)//{// qDebug() << "S:" <<S.at(i).no<< S.at(i).noK;//}return 1;
}Kmeans::~Kmeans()
{}//计算质心
void Kmeans::Calcentroid()
{centroid s;for (int i = 0; i < k.size(); i++){s.sx = 0; s.sy = 0; int iCt = 0;for (int j = 0; j < S.size(); j++){if (k.at(i).no == S.at(j).noK){s.sx = s.sx + S.at(j).x;s.sy = s.sy + S.at(j).y;iCt++;}}s.noK = k.at(i).no;s.sx = s.sx / iCt;s.sy = s.sy / iCt;dis.push_back(s);}
}//计算每个对象至聚类中心的距离
void Kmeans::CalDis()
{for (int i = 0; i < p.size(); i++){double s0 = 0; QString no; Dis ss; int t = 0;double x1 = p.at(i).x;double y1 = p.at(i).y;//double x = k.at(0).x;//double y = k.at(0).y;//s0 = sqrt((x1 - x) * (x1 - x) + (y1 - y) * (y1 - y));for (int j = 0; j < k.size(); j++){double x2 = k.at(j).x;double y2 = k.at(j).y;double s1 = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));t++;if (t == 1){s0 = s1;no = k.at(j).no;}if (s1 < s0){s0 = s1;no = k.at(j).no;}}ss.s = s0;ss.no = p.at(i).no;ss.x = p.at(i).x;ss.y = p.at(i).y;ss.noK = no;S.push_back(ss);}}//将新的质心坐标赋值给k
void Kmeans::CKmeans()
{for (int i = 0; i < k.size(); i++){for (int j = 0; j < dis.size(); j++){if (k.at(i).no == dis.at(j).noK){k.at(i).x = dis.at(j).sx;k.at(i).y = dis.at(j).sy;}}}
}//绘图函数
void Kmeans::drawPoint()
{QPicture pp;pp.setBoundingRect(ui.label_2->rect());QPainter painterP(&pp);QPen pen;painterP.setRenderHint(QPainter::Antialiasing, true);Pointp p1;p1.no = p.at(0).no;p1.x = p.at(0).x;p1.y = p.at(0).y;for (int i = 1; i < p.size(); i++){if (p1.x > p.at(i).x){p1.x = p.at(i).x;}if (p1.y > p.at(i).y){p1.y = p.at(i).y;}}double xmin = p1.x;double ymin = p1.y;for (int i = 1; i < p.size(); i++){if (p1.x < p.at(i).x){p1.x = p.at(i).x;}if (p1.y < p.at(i).y){p1.y = p.at(i).y;}}double xmax = p1.x;double ymax = p1.y;int w=ui.label_2->width();int h=ui.label_2->height();double a = w/(xmax -xmin);double b1 = h/(ymax -ymin);for (int i = 0; i < k.size(); i++){int r = qrand() % 256;int g = qrand() % 256;int b = qrand() % 256;QColor color = QColor(r, g, b);for (int j = 0; j < S.size(); j++){if (k.at(i).no == S.at(j).noK){pen.setColor(color);painterP.setPen(pen);int radius = 5;double x = S.at(j).x;double y = S.at(j).y;x = (x - xmin)*a;y = (y - ymin)*b1;painterP.drawEllipse(x - radius, y - radius, radius * 2, radius * 2);}}}ui.label_2->setPicture(pp);
}void Kmeans::CalK()
{k.push_back(p.at(0));CalDistance();while (k.size() != K){qDebug() << k.size() << k.at(k.size() - 1).no;S.clear();CalDistance();for (auto& val : k){qDebug() << "CalK.k1" << val.no << val.x << val.y;}std::vector<Pointp> vk; int t3 = k.size();while (vk.size() != t3){Pointp p9 = k.at(0); int t2 = 0;for (int i = 1; i < k.size(); i++){Pointp p2 = k.at(i);if (p9.no.toInt() < k.at(i).no.toInt()){p9 = k.at(i);t2 = i;}}k.erase(k.begin() + t2);//删除下标为t2的元素;vk.push_back(p9);}for (int i = vk.size() - 1; i >= 0; i--){k.push_back(vk.at(i));}for (auto& val : k){qDebug() <<"CalK.k" << val.no << val.x << val.y;}int cv = 1;for (auto& val : k){S.erase(S.begin() + (val.no.toInt() - cv));//删除下标为val.number的元素;cv++;}double s0 = 0;Pointp kk;kk = { 0,0,0 };for (auto& valS : S){if (s0 <= valS.s){s0 = valS.s;kk.no = valS.no;kk.x = valS.x;kk.y = valS.y;}}k.push_back(kk);}int count = 1;for (auto& val : k){val.no = count;count++;//qDebug() << val.no << val.x << val.y;}
}void Kmeans::drawK()
{QPicture pp;pp.setBoundingRect(ui.label_2->rect());QPainter painterP(&pp);QPen pen;painterP.setRenderHint(QPainter::Antialiasing, true);Pointp p1;p1.no = p.at(0).no;p1.x = p.at(0).x;p1.y = p.at(0).y;for (int i = 1; i < p.size(); i++){if (p1.x > p.at(i).x){p1.x = p.at(i).x;}if (p1.y > p.at(i).y){p1.y = p.at(i).y;}}double xmin = p1.x;double ymin = p1.y;for (int i = 1; i < p.size(); i++){if (p1.x < p.at(i).x){p1.x = p.at(i).x;}if (p1.y < p.at(i).y){p1.y = p.at(i).y;}}double xmax = p1.x;double ymax = p1.y;int w = ui.label_2->width();int h = ui.label_2->height();double a = w / (xmax - xmin);double b1 = h / (ymax - ymin);QColor color = QColor(123,223,46);for (int i = 0; i < k.size(); i++){pen.setColor(color);pen.setWidth(3);painterP.setPen(pen);int radius = 10;double x = k.at(i).x;double y = k.at(i).y;x = (x - xmin) * a;y = (y - ymin) * b1;painterP.drawEllipse(x - radius, y - radius, radius * 2, radius * 2);}ui.label_2->setPicture(pp);
}void Kmeans::CalDistance()
{Dis ss;for (auto& valP : p){double s0 = 0; int c = 1;double x1 = valP.x;double y1 = valP.y;for (auto& valK : k){double x2 = valK.x;double y2 = valK.y;x2 = x2 - x1;y2 = y2 - y1;double s = sqrt(x2 * x2 + y2 * y2);if (c == 1){s0 = s;ss.no = valP.no;ss.noK = valK.no;ss.x = valP.x;ss.y = valP.y;ss.s = s;c++;}if (s0 == 0){ss.no = valP.no;ss.noK = valK.no;ss.x = valP.x;ss.y = valP.y;ss.s = s;break;}if (s < s0){s0 = s;ss.no = valP.no;ss.noK = valK.no;ss.x = valP.x;ss.y = valP.y;ss.s = s;}}S.push_back(ss);}
}
#pragma once#include <QtWidgets/QWidget>
#include "ui_Kmeans.h"
#include<QFileDialog>
#include<QFile>
#include<QMessageBox>
#include<QTextStream>
#include<vector>
#pragma execution_character_set("UTF-8")
#include<qDebug>
#include<QPainter>
#include<QColor>
#include<QColorDialog>
#include<QPicture>
#include <algorithm>struct Pointp
{double x;double y;QString no;
};struct Dis
{double x;double y;QString no;QString noK;double s;
};struct centroid
{QString noK;double sx;double sy;
};enum Pd
{readK,to2K,blank
};class Kmeans : public QWidget
{Q_OBJECTpublic:Kmeans(QWidget *parent = nullptr);~Kmeans();public slots:void onBtReadData();int onBtCalKmeans();void onBtReadK();public:std::vector<Pointp> p;//原始数据点std::vector<Pointp> k;//各簇质心坐标int K;std::vector<Dis> S;std::vector<centroid> dis;bool start;Pd dd;public:void Calcentroid();void CKmeans();void CalDis();void drawPoint();void CalK();void drawK();void toK();void CalDistance();private:Ui::KmeansClass ui;
};
相关文章:

QT+VS实现Kmeans++
1、Kmeans的原理如下: (1)首先选取样本中任一数据点作为第一个聚类中心; (2)计算样本每一个数据点至现所有聚类中心的最近距离,并记录下来; (3)逐一挑选所…...

上位机图像处理和嵌入式模块部署(算法库的编写)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 作为图像处理的engineer来说,有时候我们需要提供上位机软件,有时候需要提供下位机程序,还有一种情况࿰…...
LeetCode1504. Count Submatrices With All Ones
文章目录 一、题目二、题解 一、题目 Given an m x n binary matrix mat, return the number of submatrices that have all ones. Example 1: Input: mat [[1,0,1],[1,1,0],[1,1,0]] Output: 13 Explanation: There are 6 rectangles of side 1x1. There are 2 rectangles…...
(每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第8章 项目整合管理(九)
博主2023年11月通过了信息系统项目管理的考试,考试过程中发现考试的内容全部是教材中的内容,非常符合我学习的思路,因此博主想通过该平台把自己学习过程中的经验和教材博主认为重要的知识点分享给大家,希望更多的人能够通过考试&a…...

帕金森早期诊断准确率提高至 90.2%,深圳先进院联合中山一院提出 GSP-GCNs 模型
中山大学附属第一医院&中科大先进院等研究团队,提出了一种深度学习模型——图信号处理-图卷积网络 (GSP-GCNs),利用从涉及声调调节的特定任务中获得的事件相关脑电图数据来诊断帕金森病。 震颤、动作迟缓、表情僵硬……提起帕金森病,多数…...

java servlet果蔬产业监管系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 java Web果蔬产业监管系统是一套完善的java web信息管理系统 serlvetdaobean mvc 模式开发 ,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主 要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5…...

Flask 入门
1. 关于 Flask Flask诞生于2010年, Armin Ronacher的一个愚人节玩笑。不过现在已经是一个用python语言基于Werkzeug工具箱编写的轻量级web开发框架,它主要面向需求简单,项目周期短的小应用。 Flask本身相当于一个内核,其他几乎所…...

微信小程序Skyline在手机端不渲染的问题之一及其解决方式
问题:电脑端是skyline渲染,手机端是webview渲染?如何解? 开发者工具 当前渲染模式:Skyline 当进行预览时手机端却是: 请注意看轮播图的显示情况 请注意看轮播图的显示情况 请注意看轮播图的显示情况 从轮播图上来看,手机端是webview渲染…...

怎样做好Code Review
Code Review方案 定义 Code Review代码评审是指在软件开发过程中,通过对源代码进行系统性检查的过程。通常的目的是查找各种缺陷,包括代码缺陷、功能实现问题、编码合理性、性能优化等;保证软件总体质量和提高开发者自身水平 code review …...

臻于至善,CodeArts Snap 二维绘图来一套不?
前言 我在体验 华为云的 CodeArts Snap 时,第一个例子就是绘制三角函数图像,功能注释写的也很简单。 业务场景中,有一类就是需要产出各种二维图形的,比如,折线图、散点图、柱状图等。 为了提前积累业务素材…...

STM32学习笔记(二) —— 调试串口
我们在调试程序时,经常会使用串口打印相关的调试信息,但是单片机串口不能直接与 PC 端的 USB 接口通讯,需要用到一个USB转串口的芯片来充当翻译的角色。我们使用的开发板上有这个芯片,所以在打印调试信息的时候直接使用USB线连接开…...
Ubuntu20.0.4下设置frpc开机自启动
目录 一、下载frp 二、解压 三、服务端部署 1.配置 2.运行 三、客户端部署 1、配置 2、后台运行 四、开机启动 1、拷贝frpc.service 2、修改配置 3、启用服务 五、ubuntu20.04使用 rc-local.service设置开机启动 1、建立开机服务添加 [Install] 段 2、授权rc-local.service 3、…...

05 Redis之Benchmark+简单动态字符串SDS+集合的底层实现
3.8 Benchmark Redis安装完毕后会自动安装一个redis-benchmark测试工具,其是一个压力测试工具,用于测试 Redis 的性能。 src目录下可找到该工具 通过 redis-benchmark –help 命令可以查看到其用法 3.8.1 测试1 3.9 简单动态字符串SDS 无论是 Redis …...
【C++】priority_queue优先队列
头文件#include <queue> 优先队列具有队列的所有特性,本质是一个堆实现的,和队列基本操作相同: top 访问队头元素 empty 队列是否为空 size 返回队列内元素个数 push 插入元素到队尾 (并排序) emplace 原地构造一个元素并插入队列 pop 弹出队头元素…...
蓝桥杯---三国游戏
问题描述 小蓝正在玩一款游戏。游戏中魏蜀吴三个国家各自拥有一定数量的士兵 X, Y, Z (一开始可以认为都为 0 )。游戏有 n 个可能会发生的事件,每个事件之 间相互独立且最多只会发生一次,当第 i 个事件发生时会分别让 X, Y, Z 增加 Ai , Bi ,Ci 。…...
设计一个分布式ID
为了保证全局唯一性可以用时间作为区分点一部分,时间尽可能细化,可以精确到毫秒,甚至是微秒和纳秒。如果是分布式系统有多态机器,可以根据机器ID再进行以下区分。如哦机器运行的特别快,1毫秒有大量ID生成,可…...

259:vue+openlayers: 显示海量多边形数据,10ms加载完成
第259个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers项目中通过WebGLVectorLayerRenderer方式加载海量多边形数据。这里相当于将海量的数据放在同一个层的source中,然后通过webglTile的方式渲染出这一层。 本示例数据为5000个多边形,加载速度超级快。 直接…...

Go Zero微服务个人探究之路(十)实战走通微服务前台请求调用的一套流程model->rpc微服务->apiHTTP调用
前言 Go语言凭借低占用,高并发等优秀特性成为后台编程语言的新星,GoZero框架由七牛云技术副总裁团队编写,目前已经成为Go微服务框架里star数量最多的框架 本文记录讲述笔者一步步走通前台向后台发出请求,后台api调用rpc服务的相…...

K8s 安装部署-Master和Minion(Node)
K8s 安装部署-Master和Minion(Node) 操作系统版本:CentOS 7.4 Master :172.20.26.167 Minion-1:172.20.26.198 Minion-2:172.20.26.210(后增加节点) ETCD:172.20.27.218 先安装部署ETCD y…...

从零学习Linux操作系统 第二十部分 mariadb数据库的管理
一、对于数据库的基本介绍 1.什么是数据库 数据库就是个高级的表格软件 2.常见数据库 Mysql Oracle mongodb db2 sqlite sqlserver … 3.Mysql (SUN -----> Oracle) 4.mariadb (Mysql的一种) 数据库中的常用名词 1.字段 :表格中的表头 2.表 &…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...

Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...

如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
Windows 下端口占用排查与释放全攻略
Windows 下端口占用排查与释放全攻略 在开发和运维过程中,经常会遇到端口被占用的问题(如 8080、3306 等常用端口)。本文将详细介绍如何通过命令行和图形化界面快速定位并释放被占用的端口,帮助你高效解决此类问题。 一、准…...

门静脉高压——表现
一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构:由肠系膜上静脉和脾静脉汇合构成,是肝脏血液供应的主要来源。淤血后果:门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血,引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...
13.10 LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析
LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析 LanguageMentor 对话式训练系统架构与实现 关键词:多轮对话系统设计、场景化提示工程、情感识别优化、LangGraph 状态管理、Ollama 私有化部署 1. 对话训练系统技术架构 采用四层架构实现高扩展性的对话训练…...