日撸 Java 三百行学习笔记day32

这篇博客介绍了如何检测无向图和有向图的连通性。通过建立连通矩阵,并利用单位矩阵进行矩阵运算,判断任意两点之间是否存在路径。代码示例展示了从数学原理到实际Java代码的转换,包括构造图类、矩阵操作以及连通性检查方法。最终,通过测试用例验证了算法的正确性。
摘要由CSDN通过智能技术生成

第 32 天: 图的连通性检测

连通无向图:如果无向图任意两个顶点都连通,则称为连通无向图
连通有向图:如果有向图任意两个顶点vi,vj,从vi到vj和从vj到vi都有路.径,则称有向图是强连通有向图.

在这个连通性检测在中,大致原理是这样的:令图的连通矩阵为M,M^{_{0}}=I为单位矩阵,只需计算M_{a}=M^{^{1}}+M^{^{2}}+M^{^{3}}+\cdots +M^{^{n-1}},其中n是节点个数,M^{_{a}}中第i行第j列元素为0的话,表示从节点i到节点j不可达。

是基于离散数学的知识,有些细节仍在学习中。

首先就是graph类

public class Graph {

	/**
	 * The connectivity matrix.
	 */
	IntMatrix connectivityMatrix;

	/**
	 *********************
	 * The first constructor.
	 * 
	 * @param paraNumNodes The number of nodes in the graph.
	 *********************
	 */
	public Graph(int paraNumNodes) {
		connectivityMatrix = new IntMatrix(paraNumNodes, paraNumNodes);
	}// Of the first constructor

	/**
	 *********************
	 * The second constructor.
	 * 
	 * @param paraMatrix The data matrix.
	 *********************
	 */
	public Graph(int[][] paraMatrix) {
		connectivityMatrix = new IntMatrix(paraMatrix);
	}// Of the second constructor

	/**
	 *********************
	 * Overrides the method claimed in Object, the superclass of any class.
	 *********************
	 */
	public String toString() {
		String resultString = "This is the connectivity matrix of the graph.\r\n" + connectivityMatrix;
		return resultString;
	}// Of toString

也和昨天的息息相关,两个矩阵相关的构造方法。

接着就是判断矩阵是否连通,运用的数学方法,最后再依次check是否矩阵中有元素为0,为0就代表着两点没有连通。其中也是有沿用昨天的方法。

/**
	 *********************
	 * Get the connectivity of the graph.
	 * 
	 * @throws Exception for internal error.
	 *********************
	 */
	public boolean getConnectivity() throws Exception {
		// Step 1. Initialize accumulated matrix: M_a = I.
		IntMatrix tempConnectivityMatrix = IntMatrix.getIdentityMatrix(connectivityMatrix.getData().length);

		// Step 2. Initialize M^1.
		IntMatrix tempMultipliedMatrix = new IntMatrix(connectivityMatrix);

		// Step 3. Determine the actual connectivity.
		for (int i = 0; i < connectivityMatrix.getData().length - 1; i++) {
			// M_a = M_a + M^k
			tempConnectivityMatrix.add(tempMultipliedMatrix);

			// M^k
			tempMultipliedMatrix = IntMatrix.multiply(tempMultipliedMatrix, connectivityMatrix);
		} // Of for i

		// Step 4. Check the connectivity.
		System.out.println("The connectivity matrix is: " + tempConnectivityMatrix);
		int[][] tempData = tempConnectivityMatrix.getData();
		for (int i = 0; i < tempData.length; i++) {
			for (int j = 0; j < tempData.length; j++) {
				if (tempData[i][j] == 0) {
					System.out.println("Node " + i + " cannot reach " + j);
					return false;
				} // Of if
			} // Of for j
		} // Of for i

		return true;
	}// Of getConnectivity

代码不难,从数学思想转化到代码上来,各个矩阵的构造方法不同。数学思想的理解,单位矩阵到矩阵的加法乘法,再遍历找出是否有非零元素,为了达到判断矩阵连通性的目的,为什么这么做是最难的对我来说。最后是测试用例以及入口:

**
	 *********************
	 * Unit test for getConnectivity.
	 *********************
	 */
	public static void getConnectivityTest() {
		// Test an undirected graph.
		int[][] tempMatrix = { { 0, 1, 0 }, { 1, 0, 1 }, { 0, 1, 0 } };
		Graph tempGraph2 = new Graph(tempMatrix);
		System.out.println(tempGraph2);

		boolean tempConnected = false;
		try {
			tempConnected = tempGraph2.getConnectivity();
		} catch (Exception ee) {
			System.out.println(ee);
		} // Of try.

		System.out.println("Is the graph connected? " + tempConnected);

		// Test a directed graph.
		// Remove one arc to form a directed graph.
		tempGraph2.connectivityMatrix.setValue(1, 0, 0);

		tempConnected = false;
		try {
			tempConnected = tempGraph2.getConnectivity();
		} catch (Exception ee) {
			System.out.println(ee);
		} // Of try.

		System.out.println("Is the graph connected? " + tempConnected);
	}// Of getConnectivityTest

	/**
	 *********************
	 * The entrance of the program.
	 * 
	 * @param args Not used now.
	 *********************
	 */
	public static void main(String args[]) {
		System.out.println("Hello!");
		Graph tempGraph = new Graph(3);
		System.out.println(tempGraph);

		// Unit test.
		getConnectivityTest();
	}// Of main

 我自己还手动运算了一遍,没有任何问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值