⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fcm.java

📁 模糊聚类算法FCM的JAVA源代码。输入data_in.txt和parameters.txt文件
💻 JAVA
字号:
/**
 * 
 */
package fcm;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * @author 吴春江 2007-4-23
 *
 */
public class FCM {

	private static final String FILE_DATA_IN = "data_in.txt";//输入的样本数据
	private static final String FILE_PAR = "parameters.txt";//参数配置
	private static final String FILE_CENTER = "center.txt";//聚类中心
	private static final String FILE_MATRIX = "matrix.txt";//隶属度矩阵
	private static final int SIZE = 10;
	
	public int numpattern;//样本数
	public int dimension;//每个样本点的维数
	public int cata;//要聚类的类别数
	public int maxcycle;//最大的迭代次数
	public double m;//参数m
	public double limit;//误差限
	
	public FCM() {
		super();
	}

	public FCM(int numpattern, int dimension, int cata, int maxcycle, double m, double limit) {
		this.numpattern = numpattern;
		this.dimension = dimension;
		this.cata = cata;
		this.maxcycle = maxcycle;
		this.m = m;
		this.limit = limit;
	}
	
	/**
	 * 读取配置文件
	 * @return
	 */
	public boolean getPar() {
        
		//打开配置文件
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(FILE_PAR));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
			
        //读取配置文件
		String line = null;
		for (int i = 0; i < 6; i++) {
			try {
				line = br.readLine();
			} catch (IOException e) {
				// TODO 自动生成 catch 块
				e.printStackTrace();
			}
			switch(i) {
			case 0: numpattern = Integer.valueOf(line); break;
			case 1: dimension = Integer.valueOf(line); break;
			case 2: cata = Integer.valueOf(line); break;
			case 3: m = Double.valueOf(line); break;
			case 4: maxcycle = Integer.valueOf(line); break;
			case 5: limit = Double.valueOf(line); break;
			}
		}
		
		return true;
	}
	
	/**
	 * 读取样本
	 * @param pattern
	 * @return
	 */
	public boolean getPattern(double[] pattern) {
		
		//打开样本文件
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(FILE_DATA_IN));
		} catch (FileNotFoundException e) {
			// TODO 自动生成 catch 块
			e.printStackTrace();
		}
		
		//读取样本文件
		String line = null;
		String regex = ",";
		int index = 0;
		while (true) {
			try {
				line = br.readLine();
			} catch (IOException e) {
				// TODO 自动生成 catch 块
				e.printStackTrace();
			}
			
			if (line == null)
				break;
			
			String[] split = line.split(regex);
			for (int i = 0; i < split.length; i++) 
				pattern[index++] = Double.valueOf(split[i]);
		}
			
		return true;
	}
	
	/**
	 * 本函数完成FCM聚类算法
     * 参数分为三组:基本聚类样本的信息、算法的参数信息、算法控制信息、输出信息。
	 * @param pattern 为样本点向量  指标为:样本指标*维数=维数指标
	 * @param dimension 每个样本的维数
	 * @param numpattern 样本的个数
	 * @param cata 分类的数目
	 * @param m fcm的重要控制参数m
	 * @param maxcycle 最大循环次数
	 * @param limit 算法结束迭代的阈值
	 * @param umatrix 输出的划分矩阵   指标为:聚类指标*样本数=样本指标
	 * @param rescenter 输出的样本的聚类中心向量  指标为:聚类指标*维数=维数指标
	 * @param result 目标函数的值
	 */
	public boolean FCM_fun(double[] pattern, int dimension, int numpattern, int cata, double m, 
			             int maxcycle, double limit, double[] umatrix, double[] rescenter, double result) {
		
		int j, i, k, t, count;
		int n_cycle;
		int n_selnum;
		int flagtemp;
		double f_temp, lastv, delta, t_temp;
		double[] v1 = new double[SIZE];
		double[] v2 = new double[SIZE];
		double min_dis = 0.001;//距离的最小值
		
		//验证输入参数的有效性
		if (cata >= numpattern || m <= 1)
			return false;
		
		//随机选取初始迭代点作为初始的聚类中心
		for (j = 0; j < cata; j++) {
			t_temp = Math.random();
			n_selnum = (int) (Math.random() * numpattern / cata + j * numpattern / cata);
			n_selnum = j * numpattern / cata;
			
			while (n_selnum * dimension > numpattern * dimension)
				n_selnum -= numpattern;
			
			for (i = 0; i < dimension; i++)
				rescenter[j * dimension + i] = pattern[n_selnum * dimension + i];
		}
		
		//开始主循环
		n_cycle = 0;
		lastv = 0;
		
		do{
			//计算划分矩阵
			for(i = 0; i < numpattern; i++) {
				flagtemp = 0;
				count = 0;
				for(j = 0;j < cata; j++) {
					f_temp = 0;
					for(t = 0;t < cata; t++) {
						for(k = 0; k < dimension; k++) {
							v1[k] = pattern[i * dimension + k];
							v2[k] = rescenter[t * dimension + k];
						}
						
						if (distance(v1, v2, dimension) > min_dis){
							f_temp += Math.pow(distance(v1, v2, dimension), -2 / (m - 1));
							}else{
								flagtemp = 1;
							}
						}
					
						for(k = 0; k < dimension; k++){
							v1[k] = pattern[i * dimension + k];
							v2[k] = rescenter[j * dimension + k];
						}
						
						if(flagtemp == 1){
		                   umatrix[j * numpattern + i] = 0;
						   flagtemp = 0;
						}
						
						//如果存在使得||Xk-Vi||=0的点置标志-1
						if(distance(v1, v2, dimension) > min_dis) {
							double shit1 = distance(v1, v2, dimension);
							double shit2 = Math.pow(shit1, -2 / (m - 1)) / f_temp;
							int shit3 = j * numpattern + i;
							umatrix[shit3] = shit2;
						}else{
							count++;
							umatrix[j * numpattern + i] = -1;
						}
				  }//end for j
				 
				// 如果存在使得||Xk-Vi||=0就让所有的与Xk不为零的类的隶属度为零。
				if(count > 0){
					for(j = 0; j < cata; j++){
						if(umatrix[j * numpattern + i] == -1){
							umatrix[j * numpattern + i] = 1 / (double)(count);
						}else
							umatrix[j * numpattern +i]=0;
					}
				}
			  }//end for i
			
			  f_temp = objectfun(umatrix, rescenter, pattern, cata, numpattern, dimension, m);
		      delta = Math.abs(f_temp - lastv);
			  lastv = f_temp;

			  //计算聚类中心的坐标
			  for(i = 0; i < cata; i++){
		          for(j = 0; j < dimension; j++){
					  f_temp = 0;
					  for(k = 0; k < numpattern; k++){
						  f_temp += Math.pow(umatrix[i * numpattern + k], m) * pattern[k * dimension + j];
					  }
					  rescenter[i * dimension + j] = f_temp;
					  f_temp = 0;
		              for(k = 0; k < numpattern; k++){
						  f_temp += Math.pow(umatrix[i * numpattern + k], m);
					  }
		              rescenter[i * dimension + j] /= f_temp;
				  }
			  }
		      n_cycle++;

		   } while(n_cycle < maxcycle && delta > limit);

		return true;
		
	}
	
	/**
	 * 计算欧氏距离
	 * @param v1
	 * @param v2
	 * @param dimension
	 * @return
	 */
	public double distance(double v1[],double v2[],double dimension) {
        //这个函数计算欧氏距离
		int i;
		double result;
		
		result = 0;
		for(i = 0; i < dimension; i++){
			result += (v1[i] - v2[i]) * (v1[i] - v2[i]);
		}
		
		result = Math.sqrt(result);
		
		return result;
	}
	
	/**
	 * 计算优化的目标函数
	 * @param u
	 * @param v
	 * @param x
	 * @param c
	 * @param pattern
	 * @param dimension
	 * @param m
	 * @return
	 */
	public double objectfun(double u[],double v[],double x[],int c,int pattern,int dimension,double m) {
        //此函数计算优化的目标函数
		int i,j,k;
		double[] v1 = new double[SIZE];
		double[] v2 = new double[SIZE];
		double object;
		
		object = 0;
		for(i = 0; i < c; i++) {
			for(j = 0; j < pattern; j++) {
				
				for(k = 0; k < dimension; k++) {
					v1[k] = x[j * dimension + k];
					v2[k] = v[i * dimension + k];
				}
				
				object += Math.pow(u[i * pattern+j], m) * distance(v1, v2, dimension) * distance(v1, v2, dimension);
			}
		}
		
		return object;
	}
	
	/**
	 * 运行FCM算法
	 *
	 */
	public void runFCM() {
		
		double[] pattern = new double[numpattern * dimension];
		double[] umatrix = new double[numpattern * cata];
		double[] rescenter = new double[cata * dimension];
		double result=0;
		
		//获取样本
		getPattern(pattern);
		
		//执行FCM_fun
		FCM_fun(pattern, dimension, numpattern, cata, m, maxcycle, limit, umatrix, rescenter, result);
			
		//输出结果
		Export(umatrix, rescenter);
	}
	
	/**
	 * 输出隶属度矩阵和聚类的中心
	 * @param umatrix
	 * @param rescenter
	 */
	public void Export(double[] umatrix, double[] rescenter) {
		String str = null;
		String tab = "	";
		
		//输出隶属度矩阵
		try {
			FileWriter matrixFileWriter = new FileWriter(FILE_MATRIX);
			
			for (int i = 0; i < numpattern; i++) {
				str = "";
				for (int j = 0; j < cata; j++) {
					str += umatrix[j * numpattern + i] + tab;
				}
				str += "\n";
				matrixFileWriter.write(str);
			}
			
			matrixFileWriter.close();
		} catch (IOException e) {
			// TODO 自动生成 catch 块
			e.printStackTrace();
		}
				
		//输出聚类的中心
		try {
			FileWriter centerFileWriter = new FileWriter(FILE_CENTER);
			
			for (int i = 0; i < cata; i++) {
				str = "";
				for (int j = 0; j < dimension; j++) {
					str += rescenter[i*dimension + j] + tab;
				}
				str += "\n";
				centerFileWriter.write(str);
			}
			
			centerFileWriter.close();
		} catch (IOException e) {
			// TODO 自动生成 catch 块
			e.printStackTrace();
		}
		
	}

	/**
	 * 主函数
	 * @param args
	 */
	public static void main(String[] args) {
		FCM fcm = new FCM();
		fcm.getPar();			
		fcm.runFCM();
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -