模糊聚类分析:已知模糊相似矩阵,利用利用平方自合成方法求传递闭包再通过取截矩阵动态聚类

ⅰ亾dé卋堺 提交于 2020-03-12 13:51:49

模糊聚类的一般步骤是:

(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
运行截图:
在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!