您的位置:首页 > 其它

模式识别(聚类分析算法))

2017-06-29 19:01 134 查看
实验一:最大最小距离聚类法

算法源程序如下:

#if 1

#include<iostream>

#include<math.h>

#define N 10

using namespace std;

struct XX

{

float a;

float b;

int flag;

}X1
={{0,0,0},{3,8,0},{2,2,0},{1,1,0},{5,3,0},{4,8,0},{6,3,0},{5,4,0},{6,4,0},{7,5,0}};

typedef struct XX X;

float Mod(X x1,X x2 )

{

return sqrt((x1.a -x2.a)*(x1.a-x2.a)+(x1.b-x2.b)*(x1.b -x2.b));

}

float Compare(float x1,float x2)

{

if(x1 < x2)

return x1;

else

return x2;

}

void Gather(struct XX X1[],struct XX Z[])

{

float arry4
,min;

for(int i=0;i<N;++i)

{

arry4[i]=0x7fffffff;

}

int length = sizeof(Z)/sizeof(struct XX),index,m;

for(int i=0;i<N;i++)

{

for(int j =0;j<N;++j)

{

if(Z[j].flag == 1)

{

arry4[j] = Mod(X1[i],Z[j]);

}

}

for(int k =0;k<N;++k)

{

if(arry4[k] != 0x7fffffff)

{

min = arry4[k];

m = k;

index = k;

break;

}

}

//////找出在聚类中心的最小值///////

for(int k =m;k<N;++k)

{

if( arry4[k] != 0x7fffffff)

{

if(arry4[k] < min)

{

min = arry4[k];

index =k;

}

}

}

X1[i].flag = index;

}

}

int main()

{

float s = 0.5,T,min,max;

struct XX Z
={{0,0,0}};int i =0;

int index;

struct XX Z1 = X1[0],Z2;

Z[0] = Z1;

Z[0].flag = 1;

float * arry1 = new float
;

float * arry2 = new float
;

float * arry3 = new float
;

for(int i =0;i< N;++i)

{

arry1[i] = Mod(X1[i],Z1);

}

max = arry1[0];

for(int i =0;i<N;++i)

{

if(arry1[i] > max)

{

index = i;

max = arry1[i];

}

}

Z2 = X1[index];

Z[index] = Z2;

Z[index].flag = 1;

T = s*Mod(Z1,Z2);

while(1)

{

for(int i =0;i<N;++i)

{

//到每一个Z的距离//

arry2[i] = Mod(X1[i],Z2);

}

for(int i=0;i<N;++i)

{

arry3[i] = Compare(arry1[i],arry2[i]);

}

max = arry3[0];

for(int i=0;i<N;++i)

{

if(arry3[i] > max)

{

max = arry3[i];

index =i;

}

}

if(max < T)

{

Gather(X1,Z);

break;

}

else

{

Z[index] = X1[index];

Z[index].flag =1;

Z2 = X1[index];

for(int i =0;i<N;++i)

{

arry1[i] = arry3[i];

}

}

}

/////////////输出聚类后的结果////////////////////

for(int j=0;j< N ;++j)

{

if((Z[j].flag == 1))

{

printf("Z[%d]:",j);

for(int i =0;i<N;++i)

{

if(X1[i].flag == j)

printf("X1[%d] ",i);

}

}

cout<<endl;

}

delete(arry1);

delete(arry2);

delete(arry3);

return 0;

}

#endif

聚类后的的结果如下:

其中Z[i]中的i代表需要分类的所有点中选择了哪一个作为聚类中心;

实验二:K-均值聚类法

K-均值聚类法的源程序如下:

#if 1

#include<iostream>

#include<math.h>

using namespace std;

struct XX

{

float a;

float b;

int flag;

}X[20] = {{0,0,0},{1,0,0},{0,1,0},{1,1,0},{2,1,0},{1,2,0},{2,2,0},{3,2,0},{6,6,0},{7,6,0},{8,6,0},{6,7,0},{7,7,0},{8,7,0},{9,7,0},{7,8,0},{8,8,0},{9,8,0},{8,9,0},{9,9,0}};

typedef struct XX Y;

float Mod(struct XX x1,struct XX x2)

{

return (sqrt((x1.a -x2.a)*(x1.a -x2.a)+(x1.b-x2.b)*(x1.b -x2.b)));

}

Y Add( struct XX x1,struct XX x2)

{

struct XX x;

x.a = x1.a +x2.a ;

x.b = x1.b +x2.b ;

return x;

}

Y& operator/(struct XX x1,int n)

{

struct XX x;

x.a = x1.a/n;

x.b = x1.b/n;

return x;

}

bool Compare(float D1,float D2)

{

if(D1>D2)return true;

else

return false;

}

bool Compare(struct XX x1,struct XX x2)

{

if((x1.a == x2.a )&& (x1.b == x2.b ))

return true;

else

return false;

}

int main()

{

int j =0,count1=0,count2=0;

struct XX Z1 = X[0],Z2 = X[1];

struct XX Z[2]={{0,0,0},{0,0,0}};

int i =0,N =20;

while(1)//Z1 = Z[0];Z2 = Z[1]

{

i =0;

N = 20;

while(i<N )

{

float D1 = Mod(X[i],Z1);

float D2 = Mod(X[i],Z2);

if(Compare(D1,D2))

{

X[i].flag = 2;

}

else

{

X[i].flag = 1;

}

++i;

}

while(N--)

{

//j = 0;

if(X[j].flag == 1)

{

Z[0] = Add(Z[0],X[j]);

count1++;

}

if(X[j].flag == 2)

{

Z[1] = Add(Z[1],X[j]);

count2++;

}

++j;

}

Z[0] = Z[0]/count1;

Z[1] = Z[1]/count2;

if(Compare(Z[0],Z1) && Compare(Z[1],Z2))

{

cout<<"Z1="<<Z1.a<<" "<<Z1.b<<endl;

cout<<"Z2="<<Z2.a<<" "<<Z2.b <<endl;

break;

}

else

{

Z1 = Z[0];

Z2 = Z[1];

j =0;

count1 =0;

count2 =0;

}

}

cout<<"class one:";

for(int i=0;i<20;++i)

{

if(X[i].flag == 1)

{

printf("X[%d] ",i);

}

}

cout<<endl;

cout<<"class two:";

for(int i=0;i<20;++i)

{

if(X[i].flag == 2)

{

printf("X[%d] ",i);

}

}

cout<<endl;

return 0;

}

#endif

聚类后的结果如下所示:

class one代表第一类的聚类结果,class two 是第二类聚类的结果;

实验三:感知器算法

感知器算法的:

#if 1

#include<iostream>

using namespace std;

#define N 2

#define M 2

//坐标点的结构//

struct X

{

int i;

int j;

}X1
={{0,0},{0,1}},X2[M]={{1,0},{1,1}};

//增广向量的结构//

struct AX

{

int x;

int y;

int z;

bool flag;

};

typedef struct AX Y;

//求俩增广向量的和//

Y Add(struct AX x1,struct AX x2)

{

struct AX temp;

temp.x = x1.x +x2.x ;

temp.y = x1.y +x2.y;

temp.z = x1.z +x2.z ;

return temp;

}

//求俩增广向量的乘积//

int Mul(struct AX x1,struct AX x2)

{

return (x1.x *x2.x +x1.y*x2.y +x1.z*x2.z );

}

int main()

{

struct AX XX[N+M];

int i=0;

//初?始º?化¡¥w1的Ì?增?广?向¨°量¢?//

for(i=0;i<N;++i)

{

XX[i].flag = true;

XX[i].x =X1[i].i ;

XX[i].y =X1[i].j ;

XX[i].z =1;

}

//初?始º?化¡¥w2的Ì?增?广?向¨°量¢?//

int m=M,k=0;

for(int j =i;m--;++j)

{

XX[j].flag = true;

XX[j].x = -X2[k].i ;

XX[j].y = -X2[k].j ;

XX[j].z =-1;

k++;

}

struct AX W={0,0,0,true};

int count=1;

while(1)

{

for(int i=0;i<N+M;++i)

{

int value =Mul(W,XX[i]);

//判断W*X的值是否小于等于0//

if(value <= 0)

{

W = Add(W,XX[i]);

XX[i].flag = false;

}

else

{

XX[i].flag = true;

}

count++;

}

int i;

for(i=0;i<N+M;++i)

{

if(XX[i].flag == false)

break;

}

if(i == N+M)

{

cout<<"W:"<<" "<<W.x <<" "<<W.y <<" "<<W.z<<endl;

break;

}

}

}

#endif

得到的增广向量最终的结果如下:

实验四:最小均方误差算法

最小均方误差的源程序:

得到的结果如下:

%LMSagl.m

function W=LMSagl(X,B,c)

max_iter=2000;

Error1=0;

iter=0;

[l,N]=size(X);

X1=X'*X;

X2=pinv(X1);

X_B=X2*X';

W=X_B*B;

Error=X*W-B;

for i=1:N

Error1=Error(i)+Error1;

end

while(iter<max_iter)&&(Error1>=eps)

B=B+c*(Error+abs(Error));

W=X_B*B;

iter=iter+1;

end

%test.m

% LMS函数

% X输入的模式列向量,校正因子c

clear all

clc

%输入模式向量

%X=[0 0 -1 -1;0 1 0 -1;1 1 -1 -1]';

X=[0 0 1;0 1 1;-1 0 1;-1 -1 -1];

B=[1 1 1 1]';

c=1; %校正因子

w=LMSagl(X,B,c)

实验结果如下:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息