图由顶点集V ( G )与边集E( G )构成,通常表示为: G = ( V , E ) ;
- 有向图:边集E中都是有向边的图
- 无向图:边集E中都是无向边的图
如果图中任意两个节点之间存在通路,那么这个图就是连通图(有向图叫全连通图,这里统一称连通图)。我们要检测一个图是否是连通图,首先的知道图的存储方式之一:邻接矩阵。
邻接矩阵可以表示出两两节点之间的关系(0表示无通路,1表示存在通路),但是只通过邻接矩阵没有办法判断该图是否连通;如A到C之间虽然没有直接通路,但是却可以通过顶点B间接到C 我们将连通矩阵记为,顶点数为n 在离散数学中有这样一个公式:
这个矩阵中的元素
代表
路径长度为
的路径数量。
举个例子:
表明顶点A到A路径长度为n=2的路径数量是1条
表明顶点A到C路径长度为n=2的路径数量是1条
表明顶点B到B路径长度为n=2的路径数量是2条
.........
而n个节点需要路径长度为n-1时便可检测出最远两个顶点的连通性,此时只需将所有的信息矩阵加起来便可以得到一个新矩阵:可达矩阵。如果可达矩阵里所有元素皆为非零元素,则该图连通。
package com.day21;
import com.day20.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 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
/**
* ********************
* Get the connectivity of the graph.
*
* @throws Exception for internal error.
* ********************
*/
public boolean getConnectivity() throws Exception {
IntMatrix tempConnectivityMatrix = IntMatrix.getIdentityMatrix(connectivityMatrix.getData().length);
IntMatrix tempMultipliedMatrix = new IntMatrix(connectivityMatrix);
for (int i = 0; i < connectivityMatrix.getData().length - 1; i++) {
tempConnectivityMatrix.add(tempMultipliedMatrix);
tempMultipliedMatrix = IntMatrix.multiply(tempMultipliedMatrix, connectivityMatrix);
} // Of for i
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() {
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);
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[]) {
getConnectivityTest();
}// Of main
}// Of class Graph
运行结果:
总结:公式的理解费了一点时间,以前离散数学欠的现在还是得补回来,顺便还知道了可以通过求的节点的出度数,
求节点的入度。图这块属于是数据结构中比较生疏的地方,相对花的时间就要多一些,以后也得回来反复复习。