模式识别(聚类分析算法))
实验一:最大最小距离聚类法算法源程序如下:#if 1#include#include#define N 10using namespace std;struct XX{float a;float b;int flag;}X1[N] ={{0,0,0},{3,8,0},{2,2,0},{1,1,0},{5,3,0},{4,8,0},{6,3,0},{5
·
实验一:最大最小距离聚类法
算法源程序如下:
#if 1
#include<iostream>
#include<math.h>
#define N 10
using namespace std;
struct XX
{
float a;
float b;
int flag;
}X1[N] ={{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[N],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[N]={{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[N];
float * arry2 = new float[N];
float * arry3 = new float[N];
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[N]={{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)
实验结果如下:
算法源程序如下:
#if 1
#include<iostream>
#include<math.h>
#define N 10
using namespace std;
struct XX
{
float a;
float b;
int flag;
}X1[N] ={{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[N],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[N]={{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[N];
float * arry2 = new float[N];
float * arry3 = new float[N];
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[N]={{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)
实验结果如下:
更多推荐
已为社区贡献1条内容
所有评论(0)