Day18——图的连通性检测

谈“图”色变……
今天看到公式的时候呆了半天,一直不明白为什么能这样做,后来慢慢的才理出点头目来,看来很有必要来复习一下离散数学了。
今天判断图的连通性主要用的公式:
M a = M 0 + M 1 + M 2 + ⋯ + M n − 1 其 中 , M 为 图 的 邻 接 矩 阵 , n 为 顶 点 数 \begin{aligned} &M_a=M^0+M^1+M^2+\cdots+M^{n-1}\\ &其中,M为图的邻接矩阵,n为顶点数 \end{aligned} Ma=M0+M1+M2++Mn1Mn
图的连通性:
无向图:

  • 如果图中任意两点是连通的,则称图是连通图。

有向图:

  • 如果图中任意两个顶点v到顶点u有路径,且顶点u到顶点v有路径,则图是强连通图。

无向图可以看作是有向图的特例,在这里我们直接讨论有向图。
现在来解释上面的公式:
首先要明白图的邻接矩阵的含义,如:
M = [ 0 1 0 1 0 1 0 1 0 ] M= \begin{bmatrix} 0&1&0\\ 1&0&1\\ 0&1&0 \end{bmatrix} M=010101010
M i j M_{ij} Mij的值表示顶点 i 是否能到达顶点 j ,若 M i j = 1 M_{ij}=1 Mij=1,表示能;否则不能。
M 0 M^0 M0是一个单位阵,主对角线的值为1,表示每个顶点都能到达其自身。
M 2 = M × M = [ 0 1 0 1 0 1 0 1 0 ] × [ 0 1 0 1 0 1 0 1 0 ] \begin{aligned} &M^2=M\times M \\ &= \begin{bmatrix} 0&1&0\\ 1&0&1\\ 0&1&0 \end{bmatrix} \times \begin{bmatrix} 0&1&0\\ 1&0&1\\ 0&1&0 \end{bmatrix} \end{aligned} M2=M×M=010101010×010101010
把矩阵乘法拆开:
M i j 2 = M i 1 × M 1 j + M i 2 × M 2 j + M i 3 × M 3 j M^2_{ij}=M_{i1}\times M_{1j}+M_{i2}\times M_{2j}+M_{i3}\times M_{3j} Mij2=Mi1×M1j+Mi2×M2j+Mi3×M3j
再结合矩阵的含义:
M i 1 表 示 i → 1 是 否 有 路 径 , M 1 j 表 示 1 → j 是 否 有 路 径 M_i1表示i\rightarrow1是否有路径,M_1j表示1\rightarrow j是否有路径 Mi1i1M1j1j
两种情况:

  • i 可到 1 ,1 可到 j,则i 可到 j,值大于0,表示i可以经过结点1到达j;
  • i 到 j 没有路径

其它同理,求和后的 M i j 2 M^2_{ij} Mij2的值表示 i 经过任意一个中转结点可到达 j 的条数。
可得, M l 中 的 M i j l 表 示 顶 点 i 到 j 的 长 度 为 l 的 通 路 数 M^l中的M_{ij}^l表示顶点i到j的长度为l的通路数 MlMijlijl

所以 M a = M 0 + M 1 + M 2 + ⋯ + M n − 1 M_a=M^0+M^1+M^2+\cdots+M^{n-1} Ma=M0+M1+M2++Mn1是概括了所有情况,如果 M a M_a Ma中还存在值为0,则该图一定是非连通图。

package day18;

import day17.IntMatrix;

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 first constructor

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

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

	/**
	 * 
	 *********************
	 * @Title: getConnectivity
	 * @Description: TODO(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.Determine the actual connectivity
		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
			tempConnectivityMatrix = IntMatrix.multiply(tempConnectivityMatrix, 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

	/**
	 * 
	 *********************
	 * @Title: getConnectivityTest
	 * @Description: TODO(Unit test for getConnectivityTest)
	 *
	 *********************
	 *
	 */
	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 e) {
			System.out.println(e);
		} // 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 e) {
			System.out.println(e);
		} // Of try.
		System.out.println("Is the graph connected? " + tempConnected);
	}// Of getConnectivityTest

	/**
	 * 
	 *********************
	 * @Title: main
	 * @Description: TODO(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
}// Graph

运行结果:
在这里插入图片描述
总结:
反推这个结论推了快一个小时,对于这块内容还是不敏感,推得我真的难受,去找个同学学习学习。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值