Brandes算法计算无向图节点最短路径之和-Java代码实现(1)

这是示例数组:

{
"nodes":[
{"id":"3.1"},
{"id":"4.1"},
{"id":"4.4"},
{"id":"2.3"},
{"id":"1.1"},
{"id":"1.2"}
],
 "edges": [
    {
      "id":"e1",
      "source": "3.1",
      "target": "4.1"
    },
    {
      "id":"e2",
      "source": "4.4",
      "target": "4.1"
    },
    {
      "id":"e3",
      "source": "3.1",
      "target": "4.4"
     },
    {
      "id":"e4",
      "source": "4.1",
      "target": "2.3"
     },
    {
      "id":"e5",
      "source": "4.4",
      "target": "1.1"
     },
    {
      "id":"e6",
      "source": "1.2",
      "target": "1.1"
     }
    ]
}

这是示例数组对应的无向图:

我们假设上图中每个节点间的距离均为“1”,如下图所示,例如,我们选取节点“3.1”计算其到其他节点最短路径之和:

“3.1”到“4.1”和“4.4”距离均为“1”,“3.1”到“1.1”和“2.3”距离均为“2”,“3.1”到“1.2”距离为“3”

那么,节点“3.1”计算其到其他节点最短路径之和为:1+1+2+2+3=9

同理,我们可以计算出其他节点的相应的最短路径之和。

三、Java代码实现

利用Brandes算法,我们能够在无向图中更轻松地计算出每个节点到其他节点最短路径之和。

以下是Java代码:

// 导入必要的库,用于处理JSON数据及集合操作
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        // 获取JSON对象,该对象包含了图的节点和边信息
        JSONObject graphJson = getJsonObject();

        // 创建邻接表表示图结构,键为节点ID,值为连接到该节点的所有节点ID列表
        Map<String, List<String>> adjacencyList = new HashMap<>();
        // 创建一个HashSet存储所有节点ID
        Set<String> nodesSet = new HashSet<>();

        // 解析JSON对象中的"nodes"数组,获取所有节点ID并添加到nodesSet中
        JSONArray nodesArray = graphJson.getJSONArray("nodes");
        for (int i = 0; i < nodesArray.length(); i++) {
            JSONObject nodeObj = nodesArray.getJSONObject(i);
            String nodeId = nodeObj.getString("id");
            nodesSet.add(nodeId);
        }

        // 解析JSON对象中的"edges"数组,构建邻接表
        JSONArray edgesArray = graphJson.getJSONArray("edges");
        for (int i = 0; i < edgesArray.length(); i++) {
            JSONObject edgeObj = edgesArray.getJSONObject(i);
            String source = edgeObj.getString("source");
            String target = edgeObj.getString("target");

            // 假设图是无向的,所以在邻接表中双向添加边
            adjacencyList.computeIfAbsent(source, k -> new ArrayList<>()).add(target);
            adjacencyList.computeIfAbsent(target, k -> new ArrayList<>()).add(source);
        }

        // 计算并存储每个节点的中介中心性
        Map<String, Double> nodeCentralities = new HashMap<>();
        for (String nodeId : nodesSet) {
            double centrality = calculateBetweennessCentrality(adjacencyList, nodeId);
            nodeCentralities.put(nodeId, centrality);
        }

        // 将节点按照其中介中心性降序排列
        List<Map.Entry<String, Double>> sortedNodes = new ArrayList<>(nodeCentralities.entrySet());
        sortedNodes.sort(Map.Entry.comparingByValue(Comparator.reverseOrder()));

        // 输出每个节点及其对应的中介中心性
        System.out.println("节点:该节点到其他节点最短路径距离之和:");
        for (Map.Entry<String, Double> entry : sortedNodes) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }

    // 从固定JSON字符串中创建并返回JSONObject
    private static JSONObject getJsonObject() {
        String jsonData = "{\"nodes\":[\n" +
                "{\"id\":\"3.1\"},\n" +
                "{\"id\":\"4.1\"},\n" +
                "{\"id\":\"4.4\"},\n" +
                "{\"id\":\"2.3\"},\n" +
                "{\"id\":\"1.1\"},\n" +
                "{\"id\":\"1.2\"}\n" +
                "],\n" +
                "\"edges\": [\n" +
                " {\n" +
                " \"id\":\"e1\",\n" +
                " \"source\": \"3.1\",\n" +
                " \"target\": \"4.1\"\n" +
                " },\n" +
                " {\n" +
                " \"id\":\"e2\",\n" +
                " \"source\": \"4.4\",\n" +
                " \"target\": \"4.1\"\n" +
                " },\n" +
                " {\n" +
                " \"id\":\"e3\",\n" +
                " \"source\": \"3.1\",\n" +
                " \"target\": \"4.4\"\n" +
                " },\n" +
                " {\n" +
                " \"id\":\"e4\",\n" +
                " \"source\": \"4.1\",\n" +
                " \"target\": \"2.3\"\n" +
                " },\n" +
                " {\n" +
                " \"id\":\"e5\",\n" +
                " \"source\": \"4.4\",\n" +
                " \"target\": \"1.1\"\n" +
                " },\n" +
                " {\n" +
                " \"id\":\"e6\",\n" +
                " \"source\": \"1.2\",\n" +
                " \"target\": \"1.1\"\n" +
                " }\n" +
                " ]\n}";

        JSONObject graphJson = new JSONObject(jsonData);
        return graphJson;
    }


    // 根据给定的邻接表和节点ID,计算该节点的中介中心性
    private static double calculateBetweennessCentrality(Map<String, List<String>> graph, String node) {
        // 初始化用于计算中介中心性的三个HashMap
        Map<String, Integer> sigma = new HashMap<>();
        Map

[video(video-8PGqMbZO-1716354551447)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=1804892953)(image-https://img-blog.csdnimg.cn/img_convert/d03a705143646f4f3f6ea879d59b2788.png)(title-必看视频!获取2024年最新Java开发全套学习资料 备注Java)]

<String, Double> delta = new HashMap<>();
        Map<String, Double> betweenness = new HashMap<>();

        // 初始化所有节点的sigma、delta和betweenness值
        for (String v : graph.keySet()) {
            sigma.put(v, 0);
            delta.put(v, 0.0);
            betweenness.put(v, 0.0);
        }

        // 设置当前节点的sigma值为1
        sigma.put(node, 1);

        // 创建队列(BFS)和栈(用于回溯),以及预处理器列表和距离映射表
        Queue<String> queue = new LinkedList<>();
        Stack<String> stack = new Stack<>();
        Map<String, List<String>> predecessors = new HashMap<>();
        Map<String, Integer> distances = new HashMap<>();

        // 初始化所有节点的预处理器列表和距离值
        for (String v : graph.keySet()) {
            predecessors.put(v, new ArrayList<>());
            distances.put(v, -1);
        }

        // 将当前节点加入队列,并设置距离为0
        queue.offer(node);
        distances.put(node, 0);

        // 开始广度优先搜索(BFS)


# 2021年Java中高级面试必备知识点总结

在这个部分总结了2019年到目前为止Java常见面试问题,取其面试核心编写成这份文档笔记,从中分析面试官的心理,摸清面试官的“套路”,可以说搞定90%以上的Java中高级面试没一点难度。

本节总结的内容涵盖了:消息队列、Redis缓存、分库分表、读写分离、设计高并发系统、分布式系统、高可用系统、SpringCloud微服务架构等一系列互联网主流高级技术的知识点。

**目录:**

![](https://img-blog.csdnimg.cn/img_convert/4a8b8d5e6363ff1764dc33bbd5a20caa.webp?x-oss-process=image/format,png)

(上述只是一个整体目录大纲,每个点里面都有如下所示的详细内容,从面试问题——分析面试官心理——剖析面试题——完美解答的一个过程)

![](https://img-blog.csdnimg.cn/img_convert/c2a985034fcc6dda72c6522b9eb04f5c.webp?x-oss-process=image/format,png)

**部分内容:**

![](https://img-blog.csdnimg.cn/img_convert/c22bdb480c51580a3ae2e1e82c9c9327.webp?x-oss-process=image/format,png)

![](https://img-blog.csdnimg.cn/img_convert/3b878aef5b948847aa78a7d188f620e1.webp?x-oss-process=image/format,png)

![](https://img-blog.csdnimg.cn/img_convert/12d6ac199953c8e82de007abf2a3ea01.webp?x-oss-process=image/format,png)



对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,**高清完整版一共是888页,需要的话可以点赞+关注**
66)]

[外链图片转存中...(img-lN829ZiU-1716404013867)]

[外链图片转存中...(img-YQ4WOQPC-1716404013867)]



对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,**高清完整版一共是888页,需要的话可以点赞+关注**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值