📄 isodata_iris.c
字号:
#include<stdio.h>
#include<math.h>
#define ClassNumTimes 10
#define DataNum 150
typedef struct sample
{
double x;
double y;
double z;
double p;
} SAMPLE;
double distance(SAMPLE a,SAMPLE b)
{
double d;
double a1=a.x, a2=a.y,a3=a.z,a4=a.p;
double b1=b.x, b2=b.y,b3=a.z,b4=b.p;
d=sqrt((a1-b1)*(a1-b1)+(a2-b2)*(a2-b2)+(a3-b3)*(a3-b3)+(a4-b4)*(a4-b4));
return d;
}
int MIN(double D[],int n)
{
int i;
int p=0;
double fmin=D[0];
for(i=1;i<n;i++)
{
if(D[i]<fmin) { fmin=D[i], p=i; }
}
return p;
}
int main()
{
SAMPLE point[DataNum]={
2.1,3.2,1.4,0.2,
4.9,3.0,1.4,0.2,
4.7,3.2,1.3,0.2,
4.6,3.1,1.2,0.2,
2.0,3.6,1.4,0.2,
2.4,3.9,1.7,0.4,
4.6,3.4,1.4,0.3,
2.0,3.4,1.2,0.2,
4.4,2.9,1.4,0.2,
4.9,3.1,1.2,0.1,
2.4,3.7,1.2,0.2,
4.8,3.4,1.6,0.2,
4.8,3.0,1.4,0.1,
4.3,3.0,1.1,0.1,
2.8,4.0,1.2,0.2,
2.7,4.4,1.2,0.4,
2.4,3.9,1.3,0.4,
2.1,3.2,1.4,0.3,
2.7,3.8,1.7,0.3,
2.1,3.8,1.2,0.3,
2.4,3.4,1.7,0.2,
2.1,3.7,1.2,0.4,
4.6,3.6,1.0,0.2,
2.1,3.3,1.7,0.2,
4.8,3.4,1.9,0.2,
2.0,3.0,1.6,0.2,
2.0,3.4,1.6,0.4,
2.2,3.2,1.2,0.2,
2.2,3.4,1.4,0.2,
4.7,3.2,1.6,0.2,
4.8,3.1,1.6,0.2,
2.4,3.4,1.2,0.4,
2.2,4.1,1.2,0.1,
2.2,4.2,1.4,0.2,
4.9,3.1,1.2,0.1,
2.0,3.2,1.2,0.2,
2.2,3.2,1.3,0.2,
4.9,3.1,1.2,0.1,
4.4,3.0,1.3,0.2,
2.1,3.4,1.2,0.2,
2.0,3.2,1.3,0.3,
4.2,2.3,1.3,0.3,
4.4,3.2,1.3,0.2,
2.0,3.2,1.6,0.6,
2.1,3.8,1.9,0.4,
4.8,3.0,1.4,0.3,
2.1,3.8,1.6,0.2,
4.6,3.2,1.4,0.2,
2.3,3.7,1.2,0.2,
2.0,3.3,1.4,0.2,
7.0,3.2,4.7,1.4,
6.4,3.2,4.2,1.2,
6.9,3.1,4.9,1.2,
2.2,2.3,4.0,1.3,
6.2,2.8,4.6,1.2,
2.7,2.8,4.2,1.3,
6.3,3.3,4.7,1.6,
4.9,2.4,3.3,1.0,
6.6,2.9,4.6,1.3,
2.2,2.7,3.9,1.4,
2.0,2.0,3.2,1.0,
2.9,3.0,4.2,1.2,
6.0,2.2,4.0,1.0,
6.1,2.9,4.7,1.4,
2.6,2.9,3.6,1.3,
6.7,3.1,4.4,1.4,
2.6,3.0,4.2,1.2,
2.8,2.7,4.1,1.0,
6.2,2.2,4.2,1.2,
2.6,2.2,3.9,1.1,
2.9,3.2,4.8,1.8,
6.1,2.8,4.0,1.3,
6.3,2.2,4.9,1.2,
6.1,2.8,4.7,1.2,
6.4,2.9,4.3,1.3,
6.6,3.0,4.4,1.4,
6.8,2.8,4.8,1.4,
6.7,3.0,2.0,1.7,
6.0,2.9,4.2,1.2,
2.7,2.6,3.2,1.0,
2.2,2.4,3.8,1.1,
2.2,2.4,3.7,1.0,
2.8,2.7,3.9,1.2,
6.0,2.7,2.1,1.6,
2.4,3.0,4.2,1.2,
6.0,3.4,4.2,1.6,
6.7,3.1,4.7,1.2,
6.3,2.3,4.4,1.3,
2.6,3.0,4.1,1.3,
2.2,2.2,4.0,1.3,
2.2,2.6,4.4,1.2,
6.1,3.0,4.6,1.4,
2.8,2.6,4.0,1.2,
2.0,2.3,3.3,1.0,
2.6,2.7,4.2,1.3,
2.7,3.0,4.2,1.2,
2.7,2.9,4.2,1.3,
6.2,2.9,4.3,1.3,
2.1,2.2,3.0,1.1,
2.7,2.8,4.1,1.3,
6.3,3.3,6.0,2.2,
2.8,2.7,2.1,1.9,
7.1,3.0,2.9,2.1,
6.3,2.9,2.6,1.8,
6.2,3.0,2.8,2.2,
7.6,3.0,6.6,2.1,
4.9,2.2,4.2,1.7,
7.3,2.9,6.3,1.8,
6.7,2.2,2.8,1.8,
7.2,3.6,6.1,2.2,
6.2,3.2,2.1,2.0,
6.4,2.7,2.3,1.9,
6.8,3.0,2.2,2.1,
2.7,2.2,2.0,2.0,
2.8,2.8,2.1,2.4,
6.4,3.2,2.3,2.3,
6.2,3.0,2.2,1.8,
7.7,3.8,6.7,2.2,
7.7,2.6,6.9,2.3,
6.0,2.2,2.0,1.2,
6.9,3.2,2.7,2.3,
2.6,2.8,4.9,2.0,
7.7,2.8,6.7,2.0,
6.3,2.7,4.9,1.8,
6.7,3.3,2.7,2.1,
7.2,3.2,6.0,1.8,
6.2,2.8,4.8,1.8,
6.1,3.0,4.9,1.8,
6.4,2.8,2.6,2.1,
7.2,3.0,2.8,1.6,
7.4,2.8,6.1,1.9,
7.9,3.8,6.4,2.0,
6.4,2.8,2.6,2.2,
6.3,2.8,2.1,1.2,
6.1,2.6,2.6,1.4,
7.7,3.0,6.1,2.3,
6.3,3.4,2.6,2.4,
6.4,3.1,2.2,1.8,
6.0,3.0,4.8,1.8,
6.9,3.1,2.4,2.1,
6.7,3.1,2.6,2.4,
6.9,3.1,2.1,2.3,
2.8,2.7,2.1,1.9,
6.8,3.2,2.9,2.3,
6.7,3.3,2.7,2.2,
6.7,3.0,2.2,2.3,
6.3,2.2,2.0,1.9,
6.2,3.0,2.2,2.0,
6.2,3.4,2.4,2.3,
2.9,3.0,2.1,1.8}; //模式样本
SAMPLE center[ClassNumTimes]; //聚类中心
SAMPLE sd[ClassNumTimes];//standard deviation标准差向量
double sdm[ClassNumTimes];//标准差向量中的最大分量(特征)
int flag[150];//每个样本所属类别
int count[ClassNumTimes];//各类别样本数
double D[ClassNumTimes]; //样本到每个聚类中心的距离
double Da[ClassNumTimes]; //各聚类域中诸样本与聚类中心间的平均距离
double Dl; //全部模式样本对其相应聚类中心的总平均距离
double Dc[ClassNumTimes]; //全部聚类中心的距离
double a=0.5;//系数
int t,t1,t2;
int i,j;
int n=0; //迭代次数
int K=3,Nl=1,S=1,C=4,L=1,I=100; //预设参数
int N=DataNum;
int Nc=1;//分类次数
for(i=0;i<ClassNumTimes;i++)
{
center[i]=point[i*N/K];
}
/*
center[0]=point[0];
for(i=1;i<ClassNum;i++)
{
center[i].x=-1;
center[i].y=-1;
center[i].z=-1;
center[i].p=-1;
}
*/
while(n<I)
{
n++;
//按近邻原则聚类
for(i=0;i<N;i++)
{
for(j=0;j<Nc;j++)
D[j]=distance(point[i],center[j]);
flag[i]=MIN(D,Nc);//注意
}
//赋初值
for(j=0;j<Nc;j++)
{
count[j]=0;
center[j].x=0;
center[j].y=0;
center[j].z=0;
center[j].p=0;
Da[j]=0;
Dl=0;
}
//修正聚类中心
for(i=0;i<N;i++)
{
j=flag[i];
center[j].x+=point[i].x;
center[j].y+=point[i].y;
center[j].z+=point[i].z;
center[j].p+=point[i].p;
count[j]++;
}
for(j=0;j<Nc;j++)
{
if(count[j])
{
center[j].x/=count[j];
center[j].y/=count[j];
center[j].z/=count[j];
center[j].p/=count[j];
}
printf("%d %d \n",Nc,count[j]);
}
//计算各聚类域中诸样本与聚类中心间的平均距离
//和全部模式样本对其相应聚类中心的总平均距离
for(i=0;i<N;i++)
{
j=flag[i];
Da[j]+=distance(point[i],center[j]);
}
for(j=0;j<Nc;j++)
{
Dl+=Da[j];
Da[j]=Da[j]/count[j];
}
Dl=Dl/N;
//进行分裂处理
if(n!=I&&(Nc<=K/2||(Nc>K/2&&((fmod(n,2)!=0)&&Nc<2*K))))
{
for(j=0;j<Nc;j++)
{
sd[j].x=0;
sd[j].y=0;
sd[j].z=0;
sd[j].p=0;
}
for(i=0;i<N;i++)
{
j=flag[i];
sd[j].x+=(point[i].x-center[j].x)*(point[i].x-center[j].x);
sd[j].y+=(point[i].y-center[j].y)*(point[i].y-center[j].y);
sd[j].z+=(point[i].z-center[j].z)*(point[i].z-center[j].z);
sd[j].p+=(point[i].p-center[j].p)*(point[i].p-center[j].p);
}
t=Nc;
for(j=0;j<t;j++)
{
double u;
sd[j].x=sqrt(sd[j].x/count[j]);
sd[j].y=sqrt(sd[j].y/count[j]);
sd[j].z=sqrt(sd[j].z/count[j]);
sd[j].p=sqrt(sd[j].p/count[j]);
if(sd[j].x>=sd[j].y)
u=sd[j].x;
else
u=sd[j].y;
if(u<sd[j].z)
u=sd[j].z;
if(u<sd[j].p)
u=sd[j].p;
if(u==sd[j].x)
{
sdm[j]=sd[j].x;
if(sdm[j]>S&&((Da[j]>Dl&&count[j]>2*(Nl+1))||Nc<=K/2))
{
center[Nc].x=center[j].x-a*sdm[j];
center[Nc].y=center[j].y;
center[Nc].z=center[j].z;
center[Nc].p=center[j].p;
center[j].x=center[j].x+a*sdm[j];
Nc++;
}
}
if(u==sd[j].y)
{
sdm[j]=sd[j].y;
if(sdm[j]>S&&((Da[j]>Dl&&count[j]>2*(Nl+1))||Nc<=K/2))
{
center[Nc].x=center[j].x;
center[Nc].z=center[j].z;
center[Nc].p=center[j].p;
center[Nc].y=center[j].y-a*sdm[j];
center[j].y=center[j].y+a*sdm[j];
Nc++;
}
}
if(u==sd[j].z)
{
sdm[j]=sd[j].z;
if(sdm[j]>S&&((Da[j]>Dl&&count[j]>2*(Nl+1))||Nc<=K/2))
{
center[Nc].x=center[j].x;
center[Nc].y=center[j].y;
center[Nc].p=center[j].p;
center[Nc].z=center[j].z-a*sdm[j];
center[j].z=center[j].z+a*sdm[j];
Nc++;
}
}
if(u==sd[j].p)
{
sdm[j]=sd[j].p;
if(sdm[j]>S&&((Da[j]>Dl&&count[j]>2*(Nl+1))||Nc<=K/2))
{
center[Nc].x=center[j].x;
center[Nc].z=center[j].z;
center[Nc].y=center[j].y;
center[Nc].p=center[j].p-a*sdm[j];
center[j].p=center[j].p+a*sdm[j];
Nc++;
}
}
}
if(Nc!=t) //进行了分裂处理
continue;
}
if(n==I) C=0; //最后一次迭代
//进行合并处理
t=0;
t1=-1;
t2=-1;
for(i=1;i<Nc;i++)
{
for(j=0;j<i;j++)
{
Dc[t]=distance(center[i],center[j]);
if(t>0&&Dc[t]<C&&Dc[t-1]>Dc[t])
Dc[t]=Dc[t-1];
else if(Dc[t]<C) { t1=j; t2=i; }//标记需要合并的
t++;
}
}
if(t1!=-1&&t2!=-1)
{
center[t1].x=(count[t1]*center[t1].x+count[t2]*center[t2].x)/(count[t1]+count[t2]);
center[t1].y=(count[t1]*center[t1].y+count[t2]*center[t2].y)/(count[t1]+count[t2]);
center[t1].z=(count[t1]*center[t1].z+count[t2]*center[t2].z)/(count[t1]+count[t2]);
center[t1].p=(count[t1]*center[t1].p+count[t2]*center[t2].p)/(count[t1]+count[t2]);
center[t2].x=-1;
center[t2].y=-1;
center[t2].z=-1;
center[t2].p=-1;//还应该把count的值修改
if(center[Nc-1].x!=-1&¢er[Nc-1].y!=-1&¢er[Nc-1].z!=-1&¢er[Nc-1].p!=-1)
{
center[t2].x=center[Nc-1].x;
center[t2].y=center[Nc-1].y;
center[t2].z=center[Nc-1].z;
center[t2].p=center[Nc-1].p;
}
Nc--;
}
}
printf("the first class:\n");
for(i=0;i<DataNum;i++)
{
if(flag[i]==0)
printf("point[%d]=(%f,%f,%f,%f)\n",i,point[i].x,point[i].y,point[i].z,point[i].p);
}
printf("the class center is (%f,%f,%f,%f)\n",center[0].x,center[0].y,center[0].z,center[0].p);
printf("\n");
printf("the secend class:\n");
for(i=0;i<DataNum;i++)
{
if(flag[i]==1)
printf("point[%d]=(%f,%f,%f,%f)\n",i,point[i].x,point[i].y,point[i].z,point[i].p);
}
printf("the class center is (%f,%f,%f,%f)\n",center[1].x,center[1].y,center[1].z,center[1].p);
printf("\n");
printf("the third class:\n");
for(i=0;i<DataNum;i++)
{
if(flag[i]==2)
printf("point[%d]=(%f,%f,%f,%f)\n",i,point[i].x,point[i].y,point[i].z,point[i].p);
}
printf("the class center is (%f,%f,%f,%f)\n",center[2].x,center[2].y,center[2].z,center[2].p);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -