一种基于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);
            }
        }
    }
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值