谈“图”色变……
今天看到公式的时候呆了半天,一直不明白为什么能这样做,后来慢慢的才理出点头目来,看来很有必要来复习一下离散数学了。
今天判断图的连通性主要用的公式:
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+⋯+Mn−1其中,M为图的邻接矩阵,n为顶点数
图的连通性:
无向图:
- 如果图中任意两点是连通的,则称图是连通图。
有向图:
- 如果图中任意两个顶点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是否有路径
Mi1表示i→1是否有路径,M1j表示1→j是否有路径
两种情况:
- 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的通路数
Ml中的Mijl表示顶点i到j的长度为l的通路数
所以 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+⋯+Mn−1是概括了所有情况,如果 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
运行结果:
总结:
反推这个结论推了快一个小时,对于这块内容还是不敏感,推得我真的难受,去找个同学学习学习。