`
mrcio_s
  • 浏览: 3992 次
  • 性别: Icon_minigender_1
  • 来自: 济南
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

用Warshall算法实现求关系的传递闭包

阅读更多
输入:文件input.txt,下面给出一个input.txt文件的格式样例。
A={a,b,c,d}
R={<a,b>,<b,a>,<b,c>,<c,d>}

输出:计算结果写入文件output.txt;也支持控制台打印。

package study;

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

/**
 * 测试Warshall算法生成关系闭包
 * @author mrcio_s
 */
public class TestClosure {

	private static final String fileName = "d:\\input.txt";//读取文件地址
	private static final String outputFileName = "d:\\output.txt";//写入文件地址
	private static final String separator = ";";//分隔符
	private static final int CLFS_JH = 0;//处理方式-集合
	private static final int CLFS_GX = 1;//处理方式-关系

	/**
	 * 测试Warshall算法生成关系闭包
	 * @author mrcio_s
	 * @param args
	 */
	public static void main(String[] args) {
		// 定义开始时间
		long start = System.currentTimeMillis();
		// 定义打印字符串
		StringBuffer sb = new StringBuffer();
		// 读取集合关系txt文件
		String str = readText(fileName);
		sb.append("\n读取到的集合及集合上的关系为:");
		sb.append("\n" + str);
		// 得到集合上的元素
		String[] element = (String[]) dealStr(str, CLFS_JH);
		// 得到集合上的关系
		String[][] relation = (String[][]) dealStr(str, CLFS_GX);
		// 将关系转换为矩阵
		int[][] M = conversionMatrix(relation, element);
		sb.append("\n初始化关系矩阵为:");
		sb.append("\n" + display(M, element.length));
		// 得到传递闭包
		M = genClosure(M, element.length);
		// 打印传递闭包
		sb.append("\n生成关系闭包矩阵为:");
		sb.append("\n" + display(M, element.length));
		// 将闭包矩阵转换为关系
		String returnStr = conversionRelations(M,element);
		// 得到要写入的文件
		sb.append("\n闭包关系为:");
		sb.append("\n" + returnStr);
		// 写入文件
		writeText(sb.toString(),outputFileName);
		// 定义结束时间
		long end = System.currentTimeMillis();
		sb.append("\n执行时间为:" + (end-start) + "毫秒");
		// 打印文件
		System.out.println(sb.toString());
	}

	/**
	 * 读取txt文件
	 * @param fileName
	 * @return
	 */
	public static String readText(String fileName) {
		// 接收读取的字符串
		StringBuffer sb = new StringBuffer();
		// 定义管道流
		BufferedReader in;
		try {
			in = new BufferedReader(new FileReader(fileName));
			String line;
			while ((line = in.readLine()) != null) {
				// 集合和关系字符串以";"分割,便于后面的解析
				sb.append(line).append(separator);
			}
			// 关闭管道流
			in.close();
		} catch (FileNotFoundException e) {
			System.err.println("找不到对应的文件,请检查:" + e.getMessage());
		} catch (IOException e) {
			System.err.println("读取文件失败,请检查:" + e.getMessage());
		}
		// 返回读取到的字符串信息
		return sb.toString();
	}

	/**
	 * 根据处理方式处理读取到的字符串信息 
	 * clfs为0:将集合中的元素放入一维数组中返回 
	 * clfs为1:将集合上的关系中每个有序对放入二维数组中返回
	 * @param str
	 * @param clfs
	 * @return
	 */
	public static Object dealStr(String str, int clfs) {
		String[] returnObj = null; // 返回字符串数组
		String[][] returnObjs = null; // 返回字符串二维数组

		String[] strs = str.split(separator);
		String[] temp = null;
		if (CLFS_JH == clfs) { // 处理集合中的元素
			temp = strs[clfs].split("=");
			returnObj = temp[1].substring(1, temp[1].length() - 2).split(",");
		} else if (CLFS_GX == clfs) { // 处理集合上的关系
			temp = strs[clfs].split("=");
			String[] tempStr = temp[1].substring(2, temp[1].length() - 3)
					.split(">,<");
			returnObjs = new String[tempStr.length][2];
			for (int i = 0; i < tempStr.length; i++) {
				String s = tempStr[i];
				returnObjs[i][0] = s.split(",")[0];
				returnObjs[i][1] = s.split(",")[1];
			}
		}
		// 返回处理结果
		return clfs == 0 ? returnObj : returnObjs;
	}

	/**
	 * 将关系转换为矩阵
	 * @param relation
	 * @param element
	 */
	public static int[][] conversionMatrix(String[][] relation, String[] element) {
		// 定义矩阵
		int[][] M = new int[element.length][element.length];
		// 将关系转换为矩阵
		for (int k = 0; k < relation.length; k++) {
			int i = 0, j = 0;
			boolean isExistRow = false;
			boolean isExistColumn = false;
			for (int l = 0; l < element.length; l++) {
				// 找到对应的行
				if (relation[k][0].equals(element[l])) {
					i = l;
					isExistRow = true;
				}
				// 找到对应的列
				if (relation[k][1].equals(element[l])) {
					j = l;
					isExistColumn = true;
				}
			}
			// 只有存在行,列时才置值为1
			if (isExistRow && isExistColumn) {
				M[i][j] = 1;
			}
		}
		// 返回矩阵
		return M;
	}

	/**
	 * 得到传递闭包
	 * @param str
	 * @param num
	 */
	public static int[][] genClosure(int[][] M, int N) {
		//Warshall算法
		for (int k = 0; k < N; k++) {
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < N; j++) {
					M[i][j] = M[i][j] + M[i][k] * M[k][j];
				}
			}
		}
		
		//将矩阵关系中非零的数值置为1
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (M[i][j] == 0) {
					continue;
				} else {
					M[i][j] = 1;
				}
			}
		}
		//重新返回矩阵关系
		return M;
	}
	
	/**
	 * 显示矩阵关系
	 * @param M
	 * @param N
	 */
	public static String display(int[][] M, int N){
		StringBuffer sb = new StringBuffer();
		// 显示关系矩阵
		for (int i = 0; i < N; i++) {
			sb.append("\t");
			for (int j = 0; j < N; j++) {
				sb.append(M[i][j]+ "  ");
			}
			sb.append("\n");
		}
		return sb.toString();
	}
	
	/**
	 * 将矩阵转换为关系
	 * @param relation
	 * @param element
	 */
	public static String conversionRelations(int[][] M, String[] element) {
		// 定义连接字符串
		StringBuffer sb = new StringBuffer();
		sb.append("t(R)={");
		String relata = "";
		String relatb = "";
		
		//遍历矩阵,拼接返回关系
		for (int i = 0; i < element.length; i++) {
			for (int j = 0; j < element.length; j++) {
				if (M[i][j] == 0) {
					continue;
				} else {
				    relata = element[i];
					relatb = element[j];
				}
				sb.append("<").append(relata).append(",").append(relatb).append(">").append(",");
			}
		}
		int index = sb.lastIndexOf(">,");
		//删除最后的逗号
		if(index > -1) {
			sb.deleteCharAt(index+1);
		}
		// 返回关系
		return sb.append("}").toString();
	}
	
	/**
	 * 写txt文件
	 * @param str
	 * @param outputFileName
	 */
	public static void writeText(String str, String outputFileName) {
		File f = new File(outputFileName);
		try {
			f.createNewFile();//创建文件
			// 定义管道流
			BufferedWriter output = new BufferedWriter(new FileWriter(f));
			// 写入文件
			output.write(str);
			// 关闭管道流
			output.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

分享到:
评论

相关推荐

    利用Warshall_算法求二元关系的可传递闭包

    《利用Warshall算法求二元关系的可传递闭包》 在离散数学中,二元关系是一个重要的概念,它描述了集合中的元素之间是否存在某种特定的联系。当需要研究这些关系并探究其性质时,有时我们需要计算关系的传递闭包。...

    离散数学实验报告——利用warshall算法求关系的传递闭包

    在给出的C语言程序代码中,首先读取关系矩阵的维度n和矩阵的元素,然后利用三重循环实现Warshall算法,更新矩阵以得到传递闭包。最后,打印出传递闭包的关系矩阵。 通过运行该程序并观察结果,我们可以直观地看到...

    传递闭包warshall算法java实现

    Warshall算法是由美国计算机科学家Stephen Warshall于1962年提出的,它主要用于计算有向图的所有节点对之间的传递闭包。在图中,如果存在一条从节点i到节点j的路径,我们称节点i可以到达节点j。而传递闭包是指在有向...

    C++编写warshall算法的传递闭包

    Warshall 算法的传递闭包实现 在计算机科学中,Warshall 算法是一种常用的图算法,用于计算图的...这段代码实现了 Warshall 算法的传递闭包,读取关系 R,计算关系矩阵,计算传递闭包,并输出传递闭包对应的关系矩阵。

    Warshall传递闭包算法

    Warshall传递闭包算法,使用C++实现Warshall传递闭包算法,对正在学习算法的同学应该挺有帮助的

    利用Warshall算法求二元关系的可传递闭包.docx

    ### Warshall算法求二元关系的可传递闭包 #### 一、背景介绍 在离散数学中,二元关系的可传递闭包是一个重要的概念,尤其是在数字图像处理、图论以及计算机科学的多个领域中都有广泛的应用。Warshall算法是由...

    c++求传递闭包

    在给定的代码中,使用了 Floyd-Warshall 算法来实现传递闭包的求解。具体步骤如下: 1. **初始化邻接矩阵**:首先定义了一个二维数组 `a[maxn][maxn]` 来存储邻接矩阵,其中 `maxn` 定义了最大的顶点数。通过输入...

    Warshall算法求传递闭包Python实现

    Warshall算法求传递闭包python实现 算法描述: Warshall在1962年提出了一个求关系的传递闭包的有效算法。其具体过程如下,设在n个元素的有限集上关系R的关系矩阵为M: (1)置新矩阵A=M; (2)i=1; (3)对所有j如果A...

    Warshall求矩阵传递闭包算法 可视化界面实现

    首先让用户输入一个关系集合,...我们可以设计一个Relation这样的类,将对关系的各种操作放入其中,然后我们在主函数中调运这个类就可以实现关系的传递闭包运算了。 通过矩阵来实现 1,0,0,0 1,1,0,1 0,1,1,0 1,0,1,1

    关系概念、传递闭包概念及warshall算法c++程序

    Warshall算法的基本思想是通过迭代的方式逐步构造传递闭包,每次迭代都会检查当前关系中是否存在一条路径,使得两个未被确定为有关系的元素之间存在传递关系。 C++程序实现Warshall算法通常涉及以下步骤: 1. 初始...

    传递闭包(Warshall算法)

    **传递闭包(Warshall算法)详解** 传递闭包是图论中的一个重要概念,它在计算机科学中有着广泛的应用,特别是在解决关系理论、有向图分析以及布尔代数等问题时。Warshall算法,以计算机科学家Alan J. Perlis的学生...

    传递闭包的C语言编程实现

    离散数学中传递闭包是用Warshall算法求的,此程序正式这种算法的C语言实现

    传递闭包Warshall算法

    实验名称:Warshall算法计算关系的传递闭包 源代码: #include using namespace std; int add(int a,int b) {if(a==0&&b==0) return 0; else if(a==0&&b==1||a==1&&b==0||a==1&&b==1) return 1; else cout...

    Warshall算法java实现.pdf

    总的来说,这个Java程序实现了Warshall算法,用于处理有向图的可达性问题,通过读取文本文件中的集合和关系,计算并输出关系的传递闭包。在实际应用中,这可以用于分析网络连接、社交网络关系或其他任何依赖于节点间...

    关系闭包的计算

    本实验旨在通过编程实践的方式帮助学习者深入理解关系闭包的概念,并熟练掌握Warshall算法用于计算关系的自反闭包、对称闭包以及传递闭包。 #### 关键概念解释 1. **自反闭包**:给定集合A上的关系R,如果对于集合...

    离散实验报告求有限集上给定关系的自反、对称和传递闭包

    离散实验报告求有限集上给定关系的自反、对称和传递闭包 在离散数学实验报告中,我们将学习如何求有限集上给定关系的自反、对称和传递闭包。这些概念是离散数学的重要组成部分,对于理解关系闭包的性质和应用具有...

    Warshall算法计算图的连通性,matlab实现_MATLAB实现_Warshall算法计算图的连通性_图连通性_

    这里我们将重点讨论如何用MATLAB来实现Warshall算法,并探索图连通性的概念。 首先,让我们理解什么是图连通性。在无向图中,如果对于任意两个不同的顶点,都存在一条路径连接它们,那么这个图被称为连通图。如果不...

    离散数学:基于Warshall算法实现的传递闭包

    非常非常非常简单,但我知道大家懒得自己动手编(doge)

    江西财经大学关系的传递闭包

    Rt类中核心的函数是Rn函数,它实现了求解传递闭包的沃许(Warshall)算法。沃许算法是一种动态规划算法,它利用了关系矩阵的性质来计算传递闭包。算法的基本原理是利用矩阵乘法的性质来实现关系的传递闭包运算,通过...

    论文研究-稀疏矩阵情况下Warshall算法的改进.pdf

    在分析稀疏矩阵情况下Warshall算法的改进时,首先需要了解Warshall算法是什么以及它在二元关系传递闭包中的应用。Warshall算法是一种经典的图论算法,用于计算布尔矩阵的传递闭包。在有向图的场景下,一个节点的传递...

Global site tag (gtag.js) - Google Analytics