JUNG 计算图属性,中心度,偏心率,直径,半径
本文介绍利用Java的第三方API JUNG 计算图中:
closeness centrality;// 图中某节点的 接近中心性/亲密中心性
betweenness centrality;// 图中某节点的 中介中心性/介数中心性
distance; // 图中两节点的最短距离
eccentricity; // 图中某节点的 偏心率/离心率
radius; // 半径
diameter. // 直径
JUNG 下载地址
https://sourceforge.net/projects/jung/files/
JUNG api参考文档:
http://jung.sourceforge.net/doc/api/overview-summary.html
预处理
JUNG 中的计算方法基于JUNG内置图类,本文基于自定义图计算图属性,故需要先将自定义图转存为JUNG图对象。
JUNG 提供 泛型接口,进行转化或创建时利用自定义边类型与节点类型即可。
以以下代码为例:
/** * 将graph.Graph 转为 JUNG.graph.Graph 过滤掉超边. * * @param g - 基于 graph.Graph * @return edu.uci.ics.jung.graph.Graph */ public static edu.uci.ics.jung.graph.Graph<Vertex, Edge> graphTransform(Graph<Vertex, Edge> g) { edu.uci.ics.jung.graph.Graph<Vertex, Edge> graph = new SparseGraph<>(); // 稀疏图 for (Vertex vertex : g.vertices()) { graph.addVertex(vertex); } for (Edge edge : g.edges()) { if (edge.sourceVertices().size() == 0) { // 超边 continue; } if (edge.sourceVertices().size() == 1) { // 有向边 graph.addEdge(edge, getVertex(edge.sourceVertices()), getVertex(edge.targetVertices()), EdgeType.DIRECTED); } else { // 无向边 Vertex existV = getVertex(edge.vertices()); graph.addEdge(edge, existV, getVertexExcept(edge.vertices(), existV), EdgeType.UNDIRECTED); } } return graph; }
如此,获得一个jung 图对象。
Closeness Centrality
/** * 计算图g中节点v的 closeness centrality. * * @param g - to be calculate. * @param v - central vertex. * @return closeness centrality. */ public static double closenessCentrality(Graph<Vertex, Edge> g, Vertex v) { edu.uci.ics.jung.graph.Graph<Vertex, Edge> graph = helper.Transformer.graphTransform(g); // 新建计算对象,传入图与待计算节点。 ClosenessCentrality<Vertex, Edge> closenessCentrality = new ClosenessCentrality<>(graph, t); // 获得 closeness centrality. double degree = closenessCentrality.getVertexScore(v); return degree; }
Betweenness Centrality
/** * 计算图g中节点v的 betweenness centrality. * * @param g - to be calculate. * @param v - central vertex. * * @return betweeness centrality. */ public static double betweennessCentrality(Graph<Vertex, Edge> g, Vertex v) { edu.uci.ics.jung.graph.Graph<Vertex, Edge> graph = helper.Transformer.graphTransform(g); // 新建计算对象,传入图与待计算节点。 BetweennessCentrality<Vertex, Edge> betweennessCentrality = new BetweennessCentrality<>(graph, t); // 获得 betweenness centrality. double degree = betweennessCentrality.getVertexScore(v); return degree; }
Distance (Dijkstra算法)
/** * 节点start和end之间的最短距离(需要区分有向图和无向图). * * @param g - to be calculated in. * @param start - from. * @param end - to. * @return distance. */ public static double distance(Graph<Vertex, Edge> g, Vertex start, Vertex end) { edu.uci.ics.jung.graph.Graph<Vertex, Edge> graph = helper.Transformer.graphTransform(g); DijkstraShortestPath<Vertex, Edge> dijkstraShortestPath = new DijkstraShortestPath<>(graph, t); // 计算由start到end的最短路径,返回值为路径上的边组 List<Edge> path = dijkstraShortestPath.getPath(start, end); // 统计总权值 double distance = 0; for (Edge edge : path) { distance += edge.getWeight(); } return distance; }
Eccentricity
在图论中,顶点的偏心率(eccentricity),用来表示连接图中的顶点到图中其它顶点之间的最大距离。
/** * 偏心率. * * @param g - to be calculated. * @param v - central vertex. * @return eccentricity of the specific vertex. */ public static double eccentricity(Graph<Vertex, Edge> g, Vertex v) { double eccentricity = 0; for (Vertex end : g.vertices()) { // 跳过 v 自身 if (v.equals(end)) { continue; } // 计算 distance 并记录最远距离 double distance = distance(g, v, end); if (distance > eccentricity) { eccentricity = distance; } } return eccentricity; }
Radius
在图论中,半径(radius)表示图的所有点的偏心率的最小值。
/** * 半径,即偏心率的最小值. * * @param g - to be calculated. * @return */ public static double radius(Graph<Vertex, Edge> g) { double radius = 2 ^ 10; // 初始极大值 // 遍历节点计算偏心率,记录偏心率最小值 for (Vertex vertex : g.vertices()) { double distance = eccentricity(g, vertex); if (radius > distance && distance > 0) { radius = distance; } } return radius; }
Diameter
在图论中,图的直径(diameter),表示取遍图的所有顶点,得到的偏心率的最大值。
/** * 直径,即偏心率的最大值. * * @param g - to be calculated. * @return */ public static double diameter(Graph<Vertex, Edge> g) { double diameter = 0; // 遍历节点计算偏心率,记录偏心率最大值 for (Vertex vertex : g.vertices()) { double distance = eccentricity(g, vertex); if (diameter < distance) { diameter = distance; } } return diameter; }