1.jgrapht需要引入外部jar包!
2.数据格式为:
[
{
"nodeId1":"起点1",
"nodeId2":"终点1"
},
{
"nodeId1":"起点2",
"nodeId2":"终点2"
},
{
"nodeId1":"起点3",
"nodeId2":"终点3"
}
]
package com.common.utils.graph;
import com.alibaba.fastjson.JSONObject;
import org.jgrapht.Graph;
import org.jgrapht.GraphPath;
import org.jgrapht.alg.shortestpath.FloydWarshallShortestPaths;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.DefaultUndirectedGraph;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.util.List;
import java.util.Set;
/**
* 网络计算工具类
*
* @param <V> the graph vertex type
* @param <E> the graph edge type
*/
public class NetworkCalculateUtils<V, E> {
private static final Logger log = LoggerFactory.getLogger(NetworkCalculateUtils.class);
/**
* 获取网络效率
* 网络效率E是指网络中所有节点对之间距离倒数之和的平均值。
*
* @param graph 图
* @param scale 最终结果保留位数
* @return 网络效率 E
*/
public Double getNetworkEfficiency(Graph<V, E> graph, int scale) {
// 获取所有顶点的集合
Set<V> vs = graph.vertexSet();
// n为网络中节点数目(图顶点个数)
int vSize = vs.size();
BigDecimal n = new BigDecimal(String.valueOf(vSize));
// 网络中所有节点对之间距离倒数之和
BigDecimal sum = new BigDecimal("0");
// The Floyd-Warshall algorithm
FloydWarshallShortestPaths<V, E> floydWarshallShortestPaths = new FloydWarshallShortestPaths<>(graph);
BigDecimal n1 = new BigDecimal("1");
for (V v : vs) {
for (V v1 : vs) {
// 获取每对节点的最短路径 length
GraphPath<V, E> path = floydWarshallShortestPaths.getPath(v, v1);
if(path == null){
continue;
}
int length = path.getLength();
// 每对节点最短路径的边集合
List<E> edgeList = path.getEdgeList();
if (length != 0) {
BigDecimal lt = new BigDecimal(String.valueOf(length));
// 计算每对节点最短距离的倒数 1/length (四舍五入保留10位小数)
BigDecimal re = n1.divide(lt, 6, BigDecimal.ROUND_HALF_UP);
// 计算每对节点最短距离的倒数的和
sum = sum.add(re);
/// 每对节点对应最短路径及长度
// log.info(v + "-->" + v1 + "-->" + edgeList + ",length = " + length);
}
}
}
// 计算(n-1)
BigDecimal rs = n.subtract(n1);
// 计算 n * (n - 1)
BigDecimal re = n.multiply(rs);
// 计算 1 / (n * (n - 1))
BigDecimal rt = 0 == re.intValue() ? new BigDecimal("0") : n1.divide(re, 6, BigDecimal.ROUND_HALF_UP);
// 计算最终结果,即rt*sum
BigDecimal result = rt.multiply(sum);
log.info("result = {}", result);
BigDecimal bigDecimal = result.setScale(scale, BigDecimal.ROUND_HALF_UP);
Double e = bigDecimal.doubleValue();
log.info("最终结果 e = {}", e);
return e;
}
/**
* 创建图对象
* @param list 图节点数据
* @return
*/
public static DefaultUndirectedGraph<String, DefaultEdge> createGraph(List<JSONObject> list){
// List<JSONObject> list = JSONObject.parseArray(json, JSONObject.class);
DefaultUndirectedGraph<String, DefaultEdge> graph = new DefaultUndirectedGraph<>(DefaultEdge.class);
for (JSONObject jo : list) {
String nodeId1 = jo.getString("nodeId1");
String nodeId2 = jo.getString("nodeId2");
graph.addVertex(nodeId1);
graph.addVertex(nodeId2);
DefaultEdge edge = graph.addEdge(nodeId1, nodeId2);
}
return graph;
}
/*public static void main(String[] args) {
String json = "";
List<JSONObject> list = JSONObject.parseArray(json, JSONObject.class);
DefaultUndirectedGraph<String, DefaultEdge> graph = new DefaultUndirectedGraph<>(DefaultEdge.class);
for (JSONObject jo : list) {
String nodeId1 = jo.getString("nodeId1");
String nodeId2 = jo.getString("nodeId2");
graph.addVertex(nodeId1);
graph.addVertex(nodeId2);
DefaultEdge edge = graph.addEdge(nodeId1, nodeId2);
}
// 调用
NetworkCalculateUtils<String, DefaultEdge> networkCalculateUtils = new NetworkCalculateUtils<>();
float networkEfficiency = networkCalculateUtils.getNetworkEfficiency(graph,4);
// 节点介数定义为网络中所有最短路径中经过该节点的路径的数目占最短路径总数的比例.
BetweennessCentrality<String, DefaultEdge> betweennessCentrality = new BetweennessCentrality<>(graph, true);
Map<String, Double> scores = betweennessCentrality.getScores();
// 边介数定义为网络中所有最短路径中经过该边的路径的数目占最短路径总数的比例.
EdgeBetweennessCentrality<String, DefaultEdge> edgeEdgeBetweennessCentrality = new EdgeBetweennessCentrality<>(graph);
Map<DefaultEdge, Double> map = edgeEdgeBetweennessCentrality.getScoresZb();
}*/
}