扁平聚类算法验证

实验内容

  • 扁平聚类:随机生成30个2维向量,将他们聚成3个簇,然后在平面上表示出来。

 

#include<iostream>
#include<vector>
#include<math.h>
#include<time.h>
using namespace std;
struct Point {
	int x;
	int y;
};
//质点与质心距离
double distance(Point point_1, Point point_2) {
	return sqrt((point_1.x - point_2.x) * (point_1.x - point_2.x) + (point_1.y - point_2.y) * (point_1.y - point_2.y));
}

//计算当前簇集的质心
Point getmycenter(vector<int> cluster[3], vector<Point>& point, int i,Point mycenter[]) {
	Point t;
	double num = cluster[i].size();
	double centerX = 0, centerY = 0;
	vector<int>::iterator it = cluster[i].begin();
	for (; it != cluster[i].end(); it++) {
		centerX += point[*it].x;
		centerY += point[*it].y;
	}
	if (num == 0)
		return mycenter[i];
	t.x = centerX / num;//计算重心
	t.y = centerY / num;
	return t;
}
//显示
void printscreen(Point mycenter[3], vector<int> cluster[], vector<Point>& point) {
	int a[51][51] = {0};
	int z[4] = {1,2,3,4};
	for (int m = 0; m < 3; m++) {
		vector<int>::iterator it = cluster[m].begin();
		for (; it != cluster[m].end(); it++) {
			a[point[*it].x][point[*it].y] = z[m];
		}
	}
	for (int i = 0; i < 3; i++) {
		a[mycenter[i].x][mycenter[i].y] = 4;//k个质心
	}
	for (int i = 0; i < 80; i++)
		cout << "-"; cout << "x";
	cout << endl;
	for (int i = 0; i < 51; i++) {
		cout << "|";
		for (int j = 0; j < 51; j++) {
			if (a[i][j] ==1)
				cout << "*" ;
			else if (a[i][j] == 2)
				cout << "@";
			else if (a[i][j] == 3)
				cout << "#";
			else if (a[i][j] == 4)
				cout << "&";
			else
		    	cout <<" ";
		}
		cout << endl;
	}
	}

void kmeans(vector<Point>& point, int n, int k) {
	vector<int> cluster[3];//容器组,一个容器存放一个簇的索引号
	Point mycenter[3];//存放k个质心的数组
	for (int i = 0; i < k; i++) {
		mycenter[i].x = point[i].x;//用前三个元素初始化k个质心
		mycenter[i].y = point[i].y;
	}
	//第一次计算各个质点到k个质心的距离,并得到第一次分配的容器组
	for (int i = 0; i < n; i++) {
		double _distance = distance(mycenter[0], point[i]);
		int label = 0;
		double num;
		for (int j = 0; j < k; j++) {
			num = distance(mycenter[j], point[i]);
			if (num < _distance){
				label = j;//获取其距离质心最近的序号
				_distance = num;
			}
		}
		cluster[label].push_back(i);//将第i个向量放入与其距离质心最近所在的簇中
	}
	for (int i = 0; i < 200; i++) {
		//计算新质心
		for (int i = 0; i < 3; i++) {
			mycenter[i] = getmycenter(cluster, point, i,mycenter);
		}
		//清空旧的容器
		for (int i = 0; i < k; i++)
			cluster[i].clear();
		//构建新的容器
		for (int i = 0; i < n; i++) {
			double _distance = distance(mycenter[0], point[i]);
			int label = 0;
			for (int j = 0; j < k; j++) {
				if (distance(mycenter[j], point[i]) < _distance)
					label = j;//获取其距离质心最近的序号
			}
			cluster[label].push_back(i);//将第i个向量放入与其距离质心最近所在的簇中
		}
	}
	printscreen(mycenter,cluster, point);
}

void input(vector<Point>& point, int n) {
	Point _point[30];
	srand((unsigned)time(NULL));//time()用系统时间初始化种。为rand()生成不同的随机种子。
	cout << "随机生成的" << n << "个数据:" << endl;
	for (int i = 0; i < 30; i++)
	{
		_point[i].x = rand() % 50 +1;//生成1~50随机数
		_point[i].y = rand() % 50 +1;
		point.push_back(_point[i]);
		cout << "第" << i + 1 << "个向量为:" << point[i].x << "\t\t" << point[i].y << endl;
	}
}
int main() {
	vector<Point> point;//质点
	int n, k;
	//cout << "请输入向量个数以及簇的个数" << endl;
	//cin >> n >> k;
	n = 30; k = 3;
	input(point,n);
	kmeans(point,n,k);
	return 0;
}

684ce82907a04188b3d9477299830328.png

 

670f77d2588a423ba4ee8bf8c84d763c.png

 

 

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0000it_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值