• 沒有找到結果。

3.4 K均值聚类算法软件实现细节分析

K均值聚类算法的部分实现细节将在下面分别介绍,算法由C语言编写,按照算法 的思想和步骤,构建函数,实现算法具体功能。

3.4.1算法内部函数的描述

关于算法内部一些定义以及函数的详述:

intN;∥定义的数据的个数

intK: //集合个数

int幸Centerlndex;//初始化质心数组的索引

double奉Center; //质心集合

double+CenterCopy;//质心集合副本

double木AllData; //数据集合

double奉}Cluster; //簇的集合

int木Top; //集合中元素的个数,也会用作栈处理

随机生成质心数组的函数CreateRandomArray(int n,int k,int事center)随机生成k个 x(O<--x<---n-1)作为起始的质心集合,首先调用srand((unsigned)time(NULL))函数及一个 for循环,实现k个数的随机生成,对此需要判断生成的随机数是否重复出现,对此问 题用另一个for循环进行判断,若重复则重新则生成该次的质心,若不重复,则加入于 质心数组中。具体流程图如图3.4所示:

17

图3-4,采tm-图

Fig.3-4 Flow Chart

函数GetIndex(double value,double幸center)用来返回距离最小的质心的序号,其中 value为比较得出的最小距离值,center则为质心的序号,返回最小质心的序号为算法中 比较重要的部分,只有得到了最小质心的序号,才能得出输入比较的数据与其中哪一个 质心最相似,此为聚类基础,也为更新聚类的基本步骤之~,数据按次序与质心数组相

比较,当与第一个质心相比较时,用一个减法得出数据与质心的最小距离,并存入一个 变量中,然后用for循环,循环执行更新最小质心序号和距离值,当发现有比前一次更 小的值时,则存储其序号值和最小的距离值,存储的最小距离值也就是更新了最小值,

待到下一次比较时如果发现更小的值再执行存储质心序号和距离值,依次执行k次,当 数据与每一个质心都比较过以后,就可以得到该数据与哪一个质心最靠近。于是 GetIndex函数完成任务。

拷贝质心数组到副本的函数void CopyCenter()用来将更新过后的质心数组存储,因 为判断整个算法是否继续执行的最主要的条件就是更新后的数组与更新前的数组不再 有任何的变化,当更新后的数组与更新前的数组不再有变化时,则可以说明算法已经执 行完毕,已经达到预期的效果,相似度已经最接近了,算法中用到了一个for循环,顺 序的比较原数组和拷贝的数组,循环执行k次,其中任一个不相同,则跳出比较,程序 从原始比较开始继续新一轮的更新聚类到更新数组再到比较,直到程序运行结束。

18

第三章K均值聚类算法及FPGA设计流程介绍

初始化质心,随机生成法的函数void InitCenterO的作用是先调用前面的函数 CreateRandomArray(N,K,Centerlndex),其中N为数据的个数,K为要随机生成的质心数 组的个数,其后随机生成k个质心,然后再将对应数据赋值给质心数组,最后需要调用 函数CopyCenter0,将现有的质心数组拷贝到质心副本。

加入一个数据到一个Cluster[index]集合的函数void AddToCluster(int index,double

value)是更新聚类比较重要的步骤,其中关键的地方在于得到数据应该存储的地方,就 是前面函数中得到的Index,将N个数据分别归类到K个簇中,刚完成了更新聚类,这 个方面在硬件方面的实现后面将会详述。

重新计算簇集合的函数voidUpdateClusterO就是上面提到的更新聚类的过程,这是 K均值聚类算法的最基本的两个步骤之一,其中函数的过程为,先执行一个for循环,

将所有的集合清空,即将TOP置O,该for循环执行结束以后,执行另一个for循环,

在循环中调用Getlndex得到与当前数据最小的质心索引,然后调用 AddToCluster(tindex,AllData[i])将得到的最小的质心索引加入到相应的集合中,至此,完 成了数据的更新聚类。

重新计算质心数组的函数void UpdateCenterO其执行过程为,重新计算质心集合,

对每一簇集合中的元素加总求平均值,即将上面更新聚类得到的聚类数组中的每一个数 都相加一遍,设置一个变量为sum,累加数组中的每一个数据,得到一个总和,至此得 到了簇i的元素和,其为一个for循环实现的,随后用一个if语句if(Top[i]>O)判别该簇 元素是否为空,然后用得出的总和与数据的个数相除sum/Top[i],得到其平均值。

图3-5聚类流程图

Fig.3—5 Clustering Flow Chart

19

图3.5为聚类流程图,判断两个数组元素是否相等的函数IsEqual(double母 centerl,double幸cemer2),其中用到一个for循环,用来挨次比较两个数组的各个数据,

总共比较了K次,该函数需要返回一个值False或者True,返回False或者True的作用 是告知主程序是否达到既定条件而中止程序的执行,当两个数组的每个数据都相同时,

则终止程序,否则继续程序直到两个数组不再有变化为止。

打印聚合结果void PrintO,该函数作用是输出算法运行得到的结果,并显式的将其 显示出来,里面也用到了一个for循环,循环执行K次,显示出最后的结果,图3.6为 更新数组流程图。

图3-6更新数组流程图

Fig.3—6 Updating Array Flow Chart

初始化聚类的各种数据的函数void InitDataO是对所有设计的函数进行初始化,

Center=(double*)malloc(sizeof(double)*K),/为质心集合申请空间。CenterIndex=(int 宰)malloc(sizeof(int)宰K), 为质心集合索引申请空间。CenterCopy=(double

・)malloc(sizeof(double)宰K),为质心集合副本申请空间。Top=(int*)malloc(sizeof(int)*K),

AllData=(double乖)malloc(sizeof(double)*N),为数据集合申请空间。Cluster=(double

・枣)malloc(sizeof(double・)章K),为簇集合申请空间。用一个for循环执行CluSter【i】=(double 宰)malloc(sizeof(double)*N),初始化K个簇集合。InitCenter0,初始化质心集合。

UpdateClusterO,初始化K个簇集合。

20

第三章K均值聚类算法及FPGA设计流程介绍

主函数给定类的个数K,将N个对象分到K个类中去,使得类内对象之间的相似 性最大,而类之间的相似性最小。mainO,intFlag=l,迭代标志,若为false,则迭代结束,

InitData0,初始化数据。用一个循环while(Flag),开始迭代。UpdateClusterO,更新各 个聚类。UpdateCenterO,更新质心数组。if(IsEqual(Center,CenterCopy)),如果本次迭代 与前次的质心聚合相等,即已收敛,结束退出并置Flag为O,否则将质心副本置为本次 迭代得到的质心集合,将质心副本置为本次迭代得到的质心集合,至上算法全部结束,

并且得到了应该得到的聚类结果。

由算法中对所有数据进行一次聚类簇的判别,即由数据与每个质心相比较,比较出 最相似的一个,放入相应的质心所在的数组,如图3.7所示:

图3—7流程图

Fig.3-7 Flow Chart

由图3.7所示,数据可同时与k个质心比较,而算法只能按次序比较,所以由此可 想到通过硬件的途径可大大的解决并行的问题,极大的增加算法执行的速度,尤其在数 据量较大,质心较多时。

相關文件