#include
#include
#define TOTALPOINT 12
#define AttSetSize 2
#defineMinPts 4
bool Neighbor[TOTALPOINT][TOTALPOINT]; //保存点与点是否相邻的二维数组
int ClusterNo[TOTALPOINT];//记录每个点属于哪个簇
int CurrentClusterNo=0;//记录当前的簇编号
struct ClusterList //用来存放直接密度可达的点
{
int data[10];//元素值
int head; //队列头
int tail;//元素长度
};
double DIstance(double DataBase1[],double DataBase2[])
{
int i;
double distance=0;
for(i=0;i
distance+=(DataBase1[i]-DataBase2[i])*(DataBase1[i]-DataBase2[i]);
}
distance=sqrt(distance);
return distance;
}
//判断是否为核心对象
bool isCenterObject(int ObjectNum)
{
int NeighborPointsNum=0;//记录邻近的点个数
int j;
//找出该点的邻近点的个数
for(j=0;j
{
if(Neighbor[ObjectNum][j]==true)
{
NeighborPointsNum++;
}
}
if(NeighborPointsNum>=MinPts)
{
return true;
}
return false;
}
//聚类划分过程
void DoCluster(int ObjectNum)
{
//int NeighborPointsNum=0;//记录邻近的点个数
int j;
ClusterList clusterList;
int temp;
if(ClusterNo[ObjectNum]<0) //判断该点是否找到过
{
if(isCenterObject(ObjectNum))
{
ClusterNo[ObjectNum]=CurrentClusterNo;//给核心对象分簇,不能一开始给其分簇,否则会影响判断该点是否被找过
clusterList.tail=-1;
clusterList.head=0;
//进入则表示为核心对象
for(j=0;j
{
if(Neighbor[ObjectNum][j]==true) //核心对象的密度直达点
{
clusterList.tail++;
clusterList.data[clusterList.tail]=j;
}
}
//对核心对象的邻居递归
while(clusterList.head<=clusterList.tail)
{
temp = clusterList.data[clusterList.head];//取出队列中的元素的原始序号
DoCluster(temp);
ClusterNo[temp]=CurrentClusterNo; //给核心对象的直达密度点划分簇
clusterList.head++;
}
//CurrentClusterNo++; //上个簇的元素已经全部找到 !!!!注意1:新簇加到这里会影响递归的核心对象的取值,所以新簇的产生不能出现在递归中
}
}
}
main()
{
double DataBase[TOTALPOINT][AttSetSize]={{1,0},{4,0},{0,1},{1,1},{2,1},{3,1},{4,1},{5,1},{0,2},{1,2},{4,2},{1,3}};//所有数据元素
int i,j;
double e=1;//克西....
//给ClusterNo[]初始化,代表对象的簇标号还未分配
for(i=0;i
{
ClusterNo[i]=-1;
}
//计算邻近
for(i=0;i
{
for(j=0;j
{
if(DIstance(DataBase[i],DataBase[j])<=e) //注意是小于等于
{
Neighbor[i][j]=true;
Neighbor[j][i]=true;
}
}
}
for(i=0;i
{
if(isCenterObject(i)&&ClusterNo[i]<0) //注意2:如果是核心对象并且没有扩散则重新建立一个簇
{
CurrentClusterNo++;
}
//聚类划分过程的函数
DoCluster(i);
}
//结果的输出
for(i=1;i<=CurrentClusterNo;i++)
{
printf("\n输出第%d簇的对象:",i);
for(j=0;j
{
if(ClusterNo[j]==i)
{
printf("%d\t",j+1);
}
}
}
}