赞
踩
数据挖掘算法之agnes。(最暴力的实现)(别看到暴力就放弃,hh)
。(来自青岛大学某学生)
自底向上的凝聚的方法。
随便一个输入样例:(8个点,最终聚成两类)
8
2
1 1
1 2
2 1
2 2
7 7
7 8
8 7
8 8
#include<stdio.h> #include<stdlib.h> #include<math.h> struct dian{ int x; int y; }d[1000]; struct zu{ int cnt; double x,y;//定义中心点 int d[500];//保存改组中的点 struct zu *next; }; //组使用带有头结点的链表来存储 int main(){ int n,k; struct zu* head = (struct zu *)malloc(sizeof(zu)); struct zu *p1,*p2,*p3,*p4,*prep4;//prep4用来记录p4的前一个节点,用来删除p4 double minDis;//量纲为距离的平方 p1 = head; printf("输入点的数量n 与最终组数k"); scanf("%d%d",&n,&k); //第一次读入n个点,并且初始为每一个点都是一个组 for(int i = 0;i < n;i++){ scanf("%d%d",&d[i].x,&d[i].y); //初始化每一簇 p2 = (struct zu *)malloc(sizeof(zu)); p2->d[0]=i; p2->cnt=1; p2->x=d[i].x; p2->y=d[i].y; p1->next=p2; p1=p2; } //循环找出最小的距离的两个簇并合并,用p3与p4记录两个簇 for(int it_cnt =0;it_cnt<n-k;it_cnt++){//n组数据,合并为k组,需要遍历n-k次 minDis = (head->next->x - head->next->next->x)*(head->next->x - head->next->next->x) +(head->next->y - head->next->next->y)*(head->next->y - head->next->next->y);//初始最小距离的平方是前两个簇的距离 p3 = head->next; prep4 = p3;//记录p4的前一个节点 p4 = head->next->next;//初始p3,p4记录最小距离的两个簇的位置 p1 = head->next; while(p1->next!=NULL){ p2=p1->next; struct zu *prep2=p1;//记录p2前面的簇,方便记录prep4 while(p2!=NULL){ //计算距离 double tmpdis = (p1->x - p2->x)*(p1->x - p2->x)+(p1->y - p2->y)*(p1->y - p2->y); if(tmpdis<minDis){//比最小距离小 minDis = tmpdis; p3=p1; p4=p2; prep4=prep2; } prep2=p2; p2=p2->next; } p1=p1->next; } //一次遍历,获得距离最近的两个簇p3,p4,将p4合并到p3,删除p4. //合并 for(int i=0;i<p4->cnt;i++){ p3->d[p3->cnt]=p4->d[i]; p3->cnt++; } //删除p4 prep4->next=p4->next; free(p4); //重新计算p3的中心点 int tempsumx=0,tempsumy=0; for(int i = 0 ;i< p3->cnt;i++){ tempsumx+=d[p3->d[i]].x; tempsumy+=d[p3->d[i]].y; } p3->x=1.0*tempsumx/p3->cnt; p3->y=1.0*tempsumy/p3->cnt; } p1=head->next; while(p1!=NULL){ printf("hello\n"); for(int i =0 ;i<p1->cnt; i++){ printf(" %d ",p1->d[i]); } p1=p1->next; } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。