Vector类是一个向量类,里面重载了加法和对整数的除法,以及两个向量空间距离.
Specify类是聚类的一个算法(这个不是很重要), 例如给出(0,0),(0,1)(4,0),(5,0)四个两维向量,希望将四个点分成两类,并求出两类中心,
进行迭代:设(0,0)(0,1)为初始中心,算出四个点离这两个中心的距离,哪个点离哪个中心近,则认为是属于该中心点的类,迭代一次,得到(0,0)(4,0)(5,0)离(0,0)比较近,属于一类,(0,1)自成一类,修改中心为(3,0)和(0,1),继续迭代,知道两次迭代出的中心值相同结束
#ifndef BASELIST_H #define BASELIST_H
class Vector{ public:
double *data;
int dim; void setdim(int m); double space(Vector& vector2);
Vector operator+(Vector& vector2); Vector operator/(int& n); bool operator==(Vector& vector2);
void SetVector(); void VectorPrint();
int mark; };
class Specify{ public: int num; //样本个数 Vector* Sample;
Vector P1;//两个中心 Vector P2; void setdata();
void setnum(int n); void category(); void Print();
};
#endif
#include "BaseList.h" #include "iostream.h" #include "malloc.h" #include "math.h" #include "stdio.h"
///设定向量维数 void Vector::setdim(int m) { dim=m; data=new double[m]; } //输入向量 void Vector::SetVector() { for(int i=0;i<dim;i++) { cout<<"the "<<i<<"th number:"; cin>>data[i]; } cout<<endl; }
Vector Vector::operator +(Vector& vector2) { int i; Vector temp; temp.setdim(vector2.dim); for(i=0;i<dim;i++) { temp.data[i]=data[i]+vector2.data[i]; }
return temp; }
Vector Vector::operator /(int& n) { for(int i=0;i<dim;i++) { data[i]=data[i]/n; } return *this; }
bool Vector::operator ==(Vector& vector2) { bool ee=true; for(int i=0;i<dim;i++) { if(data[i]!=vector2.data[i]) { ee=false; break; } } return ee; }
//两个向量之间的距离 double Vector::space(Vector &vector2) { int i; double result=0; for(i=0;i<dim;i++) { result+=pow((vector2.data[i]-data[i]),2); } return sqrt(result); } void Vector::VectorPrint() { int i; for(i=0;i<dim;i++) { cout<<data[i]<<" "; } cout<<endl; }
///////////////////////////////////////////////////
void Specify::setnum(int n) { num=n; Sample=new Vector[n]; } //初始化n个dim维向量 void Specify::setdata() { int i; int d; cout<<"input the dimension of the vectors:"<<endl; cin>>d; for(i=0;i<num;i++) { cout<<"input the"<<i<<"th sample:"; Sample[i].setdim(d); Sample[i].SetVector(); } }
////分类过程 void Specify::category() { int ch; double temp1,temp2;//两个临时变量,存放任意向量到两个中心的距离
Vector stemp1,stemp2;//存放通属于一个类的变量的和,为求新的中心作准备
bool eq=false; int i,k; P1=Sample[0]; P2=Sample[1];
stemp1.setdim(P1.dim); stemp2.setdim(P1.dim);
for(;;) { for(k=0;k<2;k++) { stemp1.data[k]=0; stemp2.data[k]=0;//<------错误就出现在这里:在第一次循环时,一切正常,可是之后,当这两个数组置零的时候,会使得P1,P2两个中心点的data值也置零,下面是跟踪显示程序~ cout<<k<<":"<<endl; cout<<"point 1:"<<endl; P1.VectorPrint(); cout<<"point 2:"<<endl; P2.VectorPrint(); } int ntemp1=0,ntemp2=0;
///计算每个向量分别到两个中心的距离并归类
for(i=0;i<num;i++) {
temp1=Sample[i].space(P1); temp2=Sample[i].space(P2); if(temp1<temp2) Sample[i].mark=1; else Sample[i].mark=2; }
///将同属一类的向量求平均得到新的中心点
for(i=0;i<num;i++) { if(Sample[i].mark==1) { stemp1=stemp1+Sample[i]; ntemp1++; } else { stemp2=stemp2+Sample[i]; ntemp2++; }
}
stemp1=(stemp1/ntemp1); stemp2=(stemp2/ntemp2); //如果两次迭代相等则成功退出,否则将更新中心点继续 if((P1==stemp1)&&(P2==stemp2)) break; else { P1=stemp1; P2=stemp2; } }
}
#include "iostream.h" #include "math.h" #include "BaseList.h" void main() {
Specify s1; s1.setnum(4); s1.setdata(); s1.category(); s1.P1.VectorPrint(); s1.P2.VectorPrint(); } 实在是不明白~~~555~~~谢谢高手指点了~~