模糊聚类的一般步骤是:
(1) 数据规格化:采用最大值规格化, 作变换
(2) 构造模糊相似矩阵:采用最大最小法来构造模糊相似矩阵R
(3) 利用平方自合成方法求传递闭包t®:依次计算R2, R4, R8…直到Rn=R2n,则Rn为所求
(4) 选取适当的置信水平值λ属于[0, 1], 按λ截矩阵t®λ 进行动态聚类 。把t®中的元素从大到小的顺序编排
(5) 绘制聚类图
下面的代码要实现的是步骤2-4,已知模糊相似矩阵,利用利用平方自合成方法求传递闭包再通过取截矩阵动态聚类,数据规格化暂不考虑,
重点:!!!我实现不了编排,太难了,有大佬能实现吗感激不尽,绘图就算了没必要。
代码在最后
下面是课件例子,已知此模糊相似矩阵,对其进行聚类
#include<cstdio>
#include<algorithm>
//#include<cstring>
//#include<cmath>
#include<iostream>
using namespace std;
//
double min(double a,double b){
if(a<=b) return a;
else return b;
}
bool cmp(double a,double b){
return a>b;
}
int main()
{
int n;
int m=2;
cin>>n;
double a[100][100]={0};//输入原矩阵
double b[100][100]={0};//输出矩阵
double com[100]={0};//计算 判断 取最大值
bool next=false;//是否进行下一次迭代
double all[10000];//所有
double kind[10000];//类数
for(int i=0;i<n;i++){
for(int j=0;j<n;j++) cin>>a[i][j];
}
while(1>0){
next=false;
for(int i=0;i<n;i++){//平方自合法 最大最小值
for(int j=0;j<n;j++){
for(int k=0;k<n;k++) com[k]=min(a[i][k],a[j][k]);//取最小
sort(com,com+n,cmp);//取最大
b[i][j]=com[0];
}
}
cout<<"R的"<<m<<"次:"<<endl;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++) cout<<b[i][j]<<" ";
cout<<endl;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(a[i][j]!=b[i][j]){//如果有不同的,就还需要迭代
next=true;
a[i][j]=b[i][j];
}
}
}
if(next!=true){
cout<<"R的"<<m/2<<"次为所求 迭代完毕"<<endl;
break;
}
m=m*2;
}
cout<<endl;
cout<<"接下来进行聚类"<<endl;
for(int i=0,k=0;i<n;i++){//把所有的值转存到一维数组all
for(int j=0;j<n;j++,k++){
all[k]=b[i][j];
}
}
sort(all,all+n*n,cmp);//对all排序
// for(int i=0;i<n*n;i++) cout<<all[i]<<" ";
// cout<<endl;
for(int i=0,j=0;i<n*n;i++,j++){//提取all中不重复的
if(all[i]!=all[i-1]) kind[j]=all[i];
if(all[i]==all[i-1]) j--;
} //kind里会有若干0,下面进行聚类时,碰到0就直接break了
for(int i=0;i<n*n;i++) {
int b2[100][101]={0};//b2是为了复制b而存在,第二维多了1是想保存每一行的行数,这样是为了编排后可以查看结果
if(kind[i]==0) break;//
cout<<"λ="<<kind[i]<<":"<<endl;
for(int j=0;j<n;j++){ //取截矩阵
for(int k=0;k<n;k++){
if(b[j][k]>=kind[i]) b2[j][k]=1;//大于兰姆达,则赋值1
else b2[j][k]=0;
if(k==n-1) b2[j][k+1]=j+1;//赋值行数
}
}
for(int j=0;j<n;j++){
for(int k=0;k<n;k++){
cout<<b2[j][k]<<" ";
}
cout<<"---- X"<<b2[j][n]<<endl;
}
}
return 0;
}
测试用例:
4
1 0.5 0.4 0.8
0.5 1 0.7 0.5
0.4 0.7 1 0.6
0.8 0.5 0.6 1
运行截图:
来源:CSDN
作者:Bug_F*cker
链接:https://blog.csdn.net/qq_42519011/article/details/104816215