DBSCAN算法C实现

#include<stdio.h>
#include<math.h>
#define TOTALPOINT 12
#define AttSetSize 2
#define	MinPts 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<AttSetSize;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<TOTALPOINT;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<TOTALPOINT;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<TOTALPOINT;i++)
	{
		ClusterNo[i]=-1;
	}
	//计算邻近
	for(i=0;i<TOTALPOINT;i++) //循环点
	{
		for(j=0;j<TOTALPOINT;j++)//查看该点与每个点是否相邻
		{
			if(DIstance(DataBase[i],DataBase[j])<=e)  //注意是小于等于
			{
				Neighbor[i][j]=true;
				Neighbor[j][i]=true;
			}
		}
	}
	for(i=0;i<TOTALPOINT;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<TOTALPOINT;j++)
		{	
			if(ClusterNo[j]==i)
			{
				printf("%d\t",j+1);
			}
		}
	}
}


你可能感兴趣的:(DBSCAN算法C实现)