1、第i类包含的素数(i=1, 2, num)/Markj:第j个样本相应的组号(j=1, 2, n)/Classifyij:第i类包含的第j素的下标int n,m,ossible;double xNM,cArrNN,zeroM; /x:每个对象由一组特征数据表征 ,cArr:存储模糊相似(等价)矩阵 double coycArrNN; /zero:辅助量每个指标均为零coycArr:传递闭包法中的中转矩阵 int cBoolArrNN; /取阈值limitLine的截关系存储至cBoolArr double centerNM,overallcenterM; /center:聚类中心overall
2、center:总体样本的中心向量 double A0NM,A1NM,vNM; /A0:c-模糊划分矩阵A1:迭代所得c-模糊划分矩阵v:聚类中心矩阵 DATA grouL,otGrou,reviseGrou; /grouL:对于每一个阈值limitLine有一个分类otGrou:最优分类/reviseGrou:ISODATA修正后得到的分类 void inut() /输入样本数据 int i,j;scanf("%d%d&,&am;n,&m); /n:样本个数m:每个样本的特征 for (i=1;i&=n;i+)for (j=1;j&=m;j+)%lf&xij); /具体数据输入 re
3、turn;void initial() /设置辅助量zero方便直接利用距离公式求得cArr初始值 int k;for (k=1;k&k+)zerok=0;double distance2(double a,double b) /求向量a,b之间的距离 double dis;dis=0;dis+=(ak-bk)*(ak-bk);return dis;void creat_conformArr() /建立模糊相似矩阵 int i,j,k;int negative=0; /指示所得矩阵是否含有负值 double dis_to_originN,tem;dis_to_origini=sqrt(dist
4、ance2(xi,zero);i+) /夹角余弦法确定xi与xj的相似程度cArrij tem=0;tem+=xik*xjk;cArrij=tem/(dis_to_origini*dis_to_originj);if (cArrij&0)negative=1;break;if (negative) /若cArr中出现负值则将矩阵全体重新调整为非负 cArrij+;cArrij/=2;void enclosure_algorithm() /传递闭包法求模糊等价矩阵 int unchanged=0; /判断是否求得传递闭包 double mergeVal;while (unchanged=0)un
5、changed=1;i+) /矩阵之间的自乘算 法 mergeVal=0;if (cArrik&=cArrkj&cArrik&mergeVal)mergeVal=cArrik;else if (cArrik&cArrkj&mergeVal=cArrkj;if (mergeVal&cArrij)coycArrij=mergeVal;unchanged=0;elsecoycArrij=cArrij;cArrij=coycArrij;void aroximate_closure() /简化模糊等价矩阵 cArrij=floor(cArrij*10+0.5)/10; /每个四舍五入到小数点第一位 in
6、t two_ower(int ) /求2的整数次幂 int i,add;add=1;=;add*=2;return add;void cluster() /基于传递闭包的聚类过程 double limitLine,limitSte,minLimit;int grouNum;int cmArrN,grouIndentifyN,grouDelegateN;int flag,count;int tem;grouNum=1;limitLine=1; /聚类阈值起始值 limitSte=0.1; /聚类阈值步长 minLimit=0.1; /聚类阈值下限k=0;while (limitLine&=min
7、Limit)k+;limitLine|fabs(cArrij-limitLine)&1e-5)cBoolArrij=1; /凡是cArrij&=limitLine的位置在0-1矩阵中均置1 cBoolArrij=0; /而cArrij&limitLine的位置置为0 tem+=cBoolArrij*two_ower(i-1);cmArrj=tem; /cmArr:将各列的值用唯一的二进制数表示方便比较 grouIndentify1=1; /当前该轮聚类分析中各素所在的组号 grouDelegate1=1; /当前该轮聚类分析中各组的代表素 /当前该轮聚类分析中的分类数即最大组号 for (i=
8、2;i+) /算法的主要部分 flag=0; /当前素是否属于已分出的组 for (count=1;count&=grouNum;count+) /如果当前的素属于已分出的组则并出其所在的组 if (cmArrgrouDelegatecount=cmArri)grouIndentifyi=count;flag=1;if (flag=0) /如果当前的素不属于任何一份出的组则将其置入新组并选该作为新组的代表 grouNum+;grouDelegategrouNum=i;grouIndentifyi=grouNum;grouk.line=limitLine; /对于每个聚类阈值确定其分组情况并存入
9、相应grouk grouk.num=grouNum;grouk.markj=grouIndentifyj;grouk.containi=0;if (grouIndentifyj=i)grouk.classifyi+grouk.containi=j;if (grouNum=1)limitLine-=limitSte;ossible=k;void redigest_grou() /将相同的分组并入一个情况使grou1grouossible为互不相同的分组 int flag;j=i+1;if (j&ossible)while (groui.num=grouj.num)j+;if (flag)for
10、(k=j;=ossible;grouk-j+i+1=grouk;ossible=ossible-j+i+1;if (i=ossible-1)double F_stat(DATA temGrou) /计算聚类temGrou的F-统计量方法 double above,below;=temGrou.num; /第i类的聚类中心向量 centerik=0;=temGrou.containi; centerik+=xtemGrou.classifyijk;centerij/=temGrou.containi;k+) /总体样本的中心向量 overallcenterk=0;overallcenterk+=
11、xjk;overallcenterk/=n;if (temGrou.num=1|temGrou.num=n)return 0;/求F值 above=0; /above:分子表征类与类之间的距离 above+=temGrou.containi*distance2(centeri,overallcenter);above/=temGrou.num-1;below=0; /below:分母表征类内样本间距离 below+=distance2(xtemGrou.classifyij,centeri);below/=n-temGrou.num;return above/below;void otlimi
12、tLine_select() /确定最佳阈值int i,ot;double max;groui.F=F_stat(groui);max=0;ot=1;if (groui.F&max) /F值越大说明分类越合理 max=groui.F;ot=i;otGrou=grouot;double matrix_model(double aN,double bN,int s,int t) /求矩阵范数|a-b|s行t列 =s;=t;dis+=(aij-bij)*(aij-bij);return sqrt(dis);void ISOdata(DATA temGrou) /将temGrou作为初始值进行ISOD
13、ATA迭代 int c;int i,j,k,rn=n;int excetN,judgeN;double tem;int is_nonemtyN;int count;c=temGrou.num;i+) exceti=0;j=0;if (temGrou.containi=1) /对于仅有一个样本的类聚类前应该排除待聚类后再加上该类excettemGrou.classifyi1=1;c-;rn-;continue;k+) if (temGrou.markk=i)A0jk=1;A0jk=0;=c;i+) /根据初始分类取初始c-模糊划分矩阵A0 if (excetj=0)A0ik=A0ij;if (i
14、=1)judgek=j;count=0;while (1)count+;=rn;A1ij=A0ij*A0ij;i+) /计算当前迭代步的聚类中心矩阵 tem+=A1ij;vik=0;vik+=A1ij*xjk;vik/=tem;i+) /修正A0得到新的A1 tem+=1/distance2(xj,vk);tem*=distance2(xj,vi);A1ij=1/tem;if (matrix_model(A0,A1,c,rn)&=1e-5) /判断是否达到迭代出口 A0ij=A1ij;if (count&1000)rintf(&OverFlown&);ste=%dn&,count);j+) /
15、将模糊划分清晰化 tem=A01j;k=1;for (i=2;if (A0ij&tem)tem=A0ij;k=i;reviseGrou.markjudgej=k; /按最大隶属度原则将xjudgej归入组号为k的类 is_nonemtyi=0; /记录已分出类的样本数目if (reviseGrou.markjudgej=i)is_nonemtyi+; /由于ISODATA给出的最终划分是退化的情形因此空集也可能成为子类 ) /重新调整组号使共有c组编号从1至c且每组非空 if (is_none mtyi=0)if (reviseGrou.markjudgek&i)reviseGrou.mark
16、judgek-;for (j=i;is_nonemtyj=is_nonemtyj+1;i+;k=c; /这时对应每一个组号的类都是非空的 if (exceti=1) /将迭代前排除的类加上 reviseGrou.marki=+k;reviseGrou.num=k; /修正后得到的最终分类类数 /reviseGrou.mark标记在最终分类中每个样本所在的组 =reviseGrou.num;reviseGrou.containi=0;if (reviseGrou.markj=i)reviseGrou.classifyi+reviseGrou.containi=j;void outut()int
17、j,k;%dn&,reviseGrou.num);x%d &,j);n&%d &,reviseGrou.markj);%d: %dn&,j,reviseGrou.containj);=reviseGrou.containj;,reviseGrou.classifyjk);int main()freoen(&in.txt&r&,stdin);out.txt&w&,stdout);inut(); /读入数据 initial(); /初始化 creat_conformArr(); /建立模糊相似矩阵 enclosure_algorithm(); /求其传递闭包 aroximate_closure(); /将得到的模糊等价矩阵的素四舍五入到一位小数 cluster(); /对阈值为00.10.91的情形做聚类 redigest_grou(); /简化分组使其不出现重复的分类方案
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1