java Graph 计算网络效率、节点介数、边介数

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();
     }*/
}

https://my.oschina.net/thinwonton/blog/3133369

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值