k-means 二维,C++实现

// 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;
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_39874268/article/details/82954974
今日推荐