// k_means.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
class Vector2
{
public:
float x;
float y;
void clear() {
this->x = 0;
this->y = 0;
}
};
void kmeans();
void kmeans_2d();
void print_Vector_vector2(vector <Vector2>);
int calcuslateDistance(vector<Vector2>, Vector2);
vector<Vector2> calcuslateNewCenter(vector<Vector2>, vector<vector <Vector2>>);
Vector2 calcuslateXY(vector<Vector2>);
bool isNoEquit(vector<Vector2>, vector<Vector2>);
int main()
{
kmeans_2d();
system("pause");
return 0;
}
void kmeans_2d() {
cout << "分几群?";
int groutnum = 0;
cin >> groutnum;
vector<vector <Vector2>> group;
vector <Vector2> ori;
ifstream inf;
inf.open("data.txt");
char c;
inf >> noskipws;
string temp = "";
Vector2 v2temp;
while (inf >> c)
{
if (c == '\n') {
float a = atof(temp.c_str());
v2temp.y = a;
ori.push_back(v2temp);
v2temp.clear();
temp = "";
}
else if (c == ',') {
float a = atof(temp.c_str());
v2temp.x = a;
temp = "";
}
else {
temp += c;
}
}
float a = atof(temp.c_str());
v2temp.y = a;
ori.push_back(v2temp);
v2temp.clear();
inf.close();
cout << "原始资料:" << ori.size() << endl;
print_Vector_vector2(ori);
vector<Vector2> center, vv2temp,center_old;
vector<float> testfloat;
for (int i = 0; i < groutnum; i++) {
group.push_back(vv2temp);//空值先附上去
center.push_back(ori[i]);
testfloat.push_back(0);
}
center_old = center;
bool centerNoEquit = true;
while (centerNoEquit)//true执行
{
for (int i = 0; i < groutnum; i++) {
group.pop_back();
}
for (int i = 0; i < groutnum; i++) {
group.push_back(vv2temp);
}
for (int i = 0; i < ori.size(); i++) {
Vector2 nowin = ori[i];
int temp_return;
temp_return = calcuslateDistance(center, nowin);
group[temp_return].push_back(nowin);
}
center=calcuslateNewCenter(center, group);
centerNoEquit=isNoEquit(center_old, center);
center_old = center;
}
for (int i = 0; i < groutnum; i++) {
cout << "第" << i+1 << "群:" << endl;
print_Vector_vector2(group[i]);
}
}
bool isNoEquit(vector<Vector2> center_old, vector<Vector2> center_new){
for (int i = 0; i < center_new.size(); i++) {
float x = fabs(center_new[i].x - center_old[i].x);
float y = fabs(center_new[i].y -center_old[i].y);
if (x<0.01 && y<0.01)
{
/*break;*/
return false;
}
}
return true;
}
int calcuslateDistance(vector<Vector2> center, Vector2 nowin) {
float shortest_distance = (center[0].x - nowin.x)*(center[0].x - nowin.x) + (center[0].y - nowin.y)*(center[0].y - nowin.y);
int centernum = 0;
for (int i = 1; i < center.size(); i++) {
float distance = (center[i].x - nowin.x)*(center[i].x - nowin.x) + (center[i].y - nowin.y)*(center[i].y - nowin.y);
if (shortest_distance > distance)
{
shortest_distance = distance;
centernum = i;
}
}
return centernum;
}
vector<Vector2> calcuslateNewCenter(vector<Vector2> center, vector<vector <Vector2>> g) {
vector<Vector2> vv2temp;
for (int i = 0; i < center.size(); i++) {
vv2temp = g[i];
center[i] = calcuslateXY(vv2temp);
}
return center;
}
Vector2 calcuslateXY(vector<Vector2> v) {
Vector2 v2temp;
float sum_X = 0, sum_Y = 0;
for (int i = 0; i < v.size(); i++) {
sum_X += v[i].x;
sum_Y += v[i].y;
}
v2temp.x = sum_X / v.size();
v2temp.y = sum_Y / v.size();
return v2temp;
}
void print_Vector_vector2(vector <Vector2> ori) {
Vector2 v2temp;
for (int i = 0; i < ori.size(); i++) {
v2temp.clear();
v2temp = ori[i];
cout << v2temp.x << " " << v2temp.y << endl;
}
}
k-means 二维,C++实现
猜你喜欢
转载自blog.csdn.net/weixin_39874268/article/details/82954974
今日推荐
周排行