探索图论中的关键算法(Java 实现)

news/2024/10/4 19:34:28/文章来源:https://blog.csdn.net/2301_79175212/article/details/142035596

“日出东海落西山 愁也一天 喜也一天 遇事不钻牛角尖”

文章目录

  • 前言
    • 文章有误敬请斧正 不胜感恩!||Day03
    • 1. 最短路径算法
      • Dijkstra算法
        • Java 实现:
      • Bellman-Ford算法
        • Java 实现:
    • 2. 最小生成树算法
      • Prim算法
        • Java 实现:
      • Kruskal算法
        • Java 实现:
    • 3. 二分图的最大匹配
      • 匈牙利算法
        • Java 实现:
    • 4. 网络流
      • Dinic算法
        • Java 实现:
  • 总结


前言

今天讲什么?:

图论是计算机科学中一个非常重要的分支,在困难题中,很多时候图论算法都能提供有效的解决方案。
通过学习这些经典的图论算法,我们可以更好地理解有关:
如何用最优的方式在节点和边之间进行数据传递的算法问题。

本文将带你初步探索图论中的几种核心算法,如最短路径算法、最小生成树、二分图匹配、网络流等,并通过Java语言为这些算法提供通俗易懂的实现和讲解。即使你对图论的理解有限,本文也会帮助你轻松掌握这些关键的算法和它们的实际应用场景。并给出我常用的模板供大家参考.


文章有误敬请斧正 不胜感恩!||Day03

提示:以下是本篇文章正文内容,


在这里插入图片描述


图论是计算机科学中的一个重要领域,涉及节点(顶点)和边的相关问题。本文深入探讨了几个关键的图论算法,包括最短路径算法、最小生成树、图匹配算法以及网络流算法,所有的实现都使用Java语言编写。

1. 最短路径算法

最短路径算法用于在加权图中寻找从一个节点到其他节点的最短路径。它们被广泛应用于GPS系统、网络路由等场景。

Dijkstra算法

Dijkstra算法用于找到带有非负权重的图中从源节点到其他节点的最短路径。该算法使用优先队列来扩展当前已知的最短距离。

Java 实现:
import java.util.*;class Dijkstra {static final int INF = Integer.MAX_VALUE;static List<List<int[]>> adj = new ArrayList<>();static int[] dist;static boolean[] visited;static void dijkstra(int start, int n) {dist = new int[n];visited = new boolean[n];Arrays.fill(dist, INF);PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));dist[start] = 0;pq.add(new int[]{0, start});while (!pq.isEmpty()) {int[] curr = pq.poll();int u = curr[1];if (visited[u]) continue;visited[u] = true;for (int[] edge : adj.get(u)) {int v = edge[0], weight = edge[1];if (dist[v] > dist[u] + weight) {dist[v] = dist[u] + weight;pq.add(new int[]{dist[v], v});}}}}public static void main(String[] args) {// 初始化图int n = 5;for (int i = 0; i < n; i++) adj.add(new ArrayList<>());// 添加边 (节点, 权重)adj.get(0).add(new int[]{1, 2});adj.get(1).add(new int[]{2, 1});adj.get(0).add(new int[]{2, 4});dijkstra(0, n);System.out.println(Arrays.toString(dist));}
}

Bellman-Ford算法

Bellman-Ford算法可以处理包含负权重的图,它通过多次松弛所有的边来寻找最短路径,并检测是否存在负权重环。

Java 实现:
import java.util.Arrays;class BellmanFord {static class Edge {int u, v, w;Edge(int u, int v, int w) {this.u = u;this.v = v;this.w = w;}}static final int INF = Integer.MAX_VALUE;static Edge[] edges;static int[] dist;static int n, m;static void bellmanFord(int start) {dist = new int[n];Arrays.fill(dist, INF);dist[start] = 0;for (int i = 0; i < n - 1; i++) {for (Edge e : edges) {if (dist[e.u] != INF && dist[e.u] + e.w < dist[e.v]) {dist[e.v] = dist[e.u] + e.w;}}}}public static void main(String[] args) {n = 5; m = 5;edges = new Edge[]{new Edge(0, 1, -1),new Edge(0, 2, 4),new Edge(1, 2, 3),new Edge(1, 3, 2),new Edge(1, 4, 2)};bellmanFord(0);System.out.println(Arrays.toString(dist));}
}

2. 最小生成树算法

最小生成树(MST)是涵盖图中所有顶点且具有最小边权重和的树。它们广泛应用于网络设计问题,如道路、通信网络的构建等。

Prim算法

Prim算法通过逐步扩展当前树的最小边来构建MST,适用于密集图。

Java 实现:
import java.util.Arrays;class Prim {static final int INF = Integer.MAX_VALUE;static int[][] graph;static boolean[] visited;static int[] dist;static int prim(int n) {dist = new int[n];visited = new boolean[n];Arrays.fill(dist, INF);dist[0] = 0;int res = 0;for (int i = 0; i < n; i++) {int t = -1;for (int j = 0; j < n; j++) {if (!visited[j] && (t == -1 || dist[j] < dist[t])) t = j;}if (dist[t] == INF) return -1;visited[t] = true;res += dist[t];for (int j = 0; j < n; j++) {dist[j] = Math.min(dist[j], graph[t][j]);}}return res;}public static void main(String[] args) {int n = 5;graph = new int[n][n];for (int[] row : graph) Arrays.fill(row, INF);graph[0][1] = 2;graph[1][2] = 3;graph[0][2] = 1;System.out.println(prim(n));}
}

Kruskal算法

Kruskal算法是一种贪心算法,通过排序所有边并不断选择最小边来构建MST,确保不会形成环。

Java 实现:
import java.util.*;class Kruskal {static class Edge implements Comparable<Edge> {int u, v, weight;Edge(int u, int v, int weight) {this.u = u;this.v = v;this.weight = weight;}public int compareTo(Edge other) {return Integer.compare(this.weight, other.weight);}}static int[] parent;static int find(int x) {if (parent[x] != x) parent[x] = find(parent[x]);return parent[x];}static void union(int u, int v) {parent[find(u)] = find(v);}static int kruskal(List<Edge> edges, int n) {Collections.sort(edges);parent = new int[n];for (int i = 0; i < n; i++) parent[i] = i;int mstWeight = 0;for (Edge e : edges) {if (find(e.u) != find(e.v)) {mstWeight += e.weight;union(e.u, e.v);}}return mstWeight;}public static void main(String[] args) {List<Edge> edges = new ArrayList<>();edges.add(new Edge(0, 1, 10));edges.add(new Edge(1, 2, 6));edges.add(new Edge(0, 2, 5));System.out.println(kruskal(edges, 3));}
}

3. 二分图的最大匹配

最大匹配问题涉及将二分图中两个不相交的集合顶点进行配对,以使配对数最大。

匈牙利算法

匈牙利算法用于求解二分图中的最大匹配问题。

Java 实现:
import java.util.*;class Hungarian {static List<List<Integer>> adj = new ArrayList<>();static int[] match;static boolean[] visited;static int n;static boolean dfs(int u) {for (int v : adj.get(u)) {if (!visited[v]) {visited[v] = true;if (match[v] == -1 || dfs(match[v])) {match[v] = u;return true;}}}return false;}static int hungarian() {match = new int[n];Arrays.fill(match, -1);int result = 0;for (int i = 0; i < n; i++) {visited = new boolean[n];if (dfs(i)) result++;}return result;}public static void main(String[] args) {n = 5;for (int i = 0; i < n; i++) adj.add(new ArrayList<>());adj.get(0).add(1);adj.get(1).add(2);System.out.println(hungarian());}
}

4. 网络流

网络流算法解决的是关于网络中的传输、循环和流量分配问题。

Dinic算法

Dinic算法通过构建分层图和阻塞流来高效地求解最大流问题。

Java 实现:
import java.util.*;class Dinic {static class Edge {int v, flow, capacity;Edge rev;Edge(int v, int capacity) {this.v = v;this.capacity = capacity;this.flow = 0;}}static List<List<Edge>> adj = new ArrayList<>();static int[] level;static int n;static void addEdge(int u, int v, int capacity) {Edge uv = new Edge(v, capacity);Edge vu = new Edge(u, 0);uv.rev = vu;vu.rev = uv;adj.get(u).add(uv);adj.get(v).add(vu);}static boolean bfs(int s, int t) {Arrays.fill(level, -1);Queue<Integer> q = new LinkedList<>();level[s] = 0;q.add(s);while (!q.isEmpty()) {int u = q.poll();for (Edge e : adj.get(u)) {if (level[e.v] == -1 && e.flow < e.capacity) {level[e.v] = level[u] + 1;q.add(e.v);}}}return level[t] != -1;}static int dfs(int u, int t, int flow) {if (u == t) return flow;int totalFlow = 0;for (Edge e : adj.get(u)) {if (level[e.v] == level[u] + 1 && e.flow < e.capacity) {int currFlow = dfs(e.v, t, Math.min(flow, e.capacity - e.flow));if (currFlow > 0) {e.flow += currFlow;e.rev.flow -= currFlow;totalFlow += currFlow;flow -= currFlow;if (flow == 0) break;}}}return totalFlow;}static int dinic(int s, int t) {int maxFlow = 0;level = new int[n];while (bfs(s, t)) {maxFlow += dfs(s, t, Integer.MAX_VALUE);}return maxFlow;}public static void main(String[] args) {n = 6;for (int i = 0; i < n; i++) adj.add(new ArrayList<>());addEdge(0, 1, 16);addEdge(0, 2, 13);addEdge(1, 2, 10);addEdge(2, 3, 14);addEdge(3, 4, 7);System.out.println(dinic(0, 4));}
}

总结

在这里插入图片描述


通过本文的学习,我们深入探讨了图论中的几个核心算法,并且用Java进行了详细的实现。这些算法不仅仅是理论上的工具,它们在实际问题中有着广泛的应用:

  • 最短路径算法 帮助我们在各种网络中找到最有效的传输路径,比如导航系统或通信网络。
  • 最小生成树算法 能帮助我们以最低成本构建网络,广泛应用于电网、道路建设等。
  • 二分图匹配算法 则在资源分配、任务调度等问题中提供了最佳的解决方案。
  • 网络流算法 通过优化资源流动,解决了物流、流量控制等领域中的实际问题。

掌握这些经典算法,
记住这些模板
不仅能提升帮我们打比赛,还可以为我们在实际开发中提供强大的工具。
希望通过本文的学习,图论算法我们已经初步了解了
多做题,并不断应用才能更好的掌握.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ldbm.cn/p/440015.html

如若内容造成侵权/违法违规/事实不符,请联系编程新知网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分解+优化+组合+对比!核心无忧!VMD-SSA-Transformer-LSTM多变量时间序列光伏功率预测

分解优化组合对比&#xff01;核心无忧&#xff01;VMD-SSA-Transformer-LSTM多变量时间序列光伏功率预测 目录 分解优化组合对比&#xff01;核心无忧&#xff01;VMD-SSA-Transformer-LSTM多变量时间序列光伏功率预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.…

鸿蒙开发笔记_电商严选01_登录页面(静态页面)

由于上班较忙,抽空闲暇时间,快速更新中。。。 效果图 登录页面(静态页面) import CommonConstants from ./CommonConstants;/*** 登录页面*/ // 输入文本框,的自定义样式扩展 // @Extend装饰器表示继承、扩展的意思。这里代表:自定义样式扩展 @Extend(TextInput) functio…

Python OpenCV精讲系列 - 入门指南(一)

&#x1f496;&#x1f496;⚡️⚡️ 专栏&#xff1a;Python OpenCV精讲 ⚡️⚡️&#x1f496;&#x1f496; 本专栏聚焦于Python结合OpenCV库进行计算机视觉开发的专业教程。通过系统化的课程设计&#xff0c;从基础概念入手&#xff0c;逐步深入到图像处理、特征检测、物体…

142. Go操作Kafka(confluent-kafka-go库)

文章目录 Apache kafka简介开始使用Apache Kafka构建生产者构建消费者 总结 之前已经有两篇文章介绍过 Go如何操作 kafka 28.windows安装kafka&#xff0c;Go操作kafka示例&#xff08;sarama库&#xff09; 51.Go操作kafka示例&#xff08;kafka-go库&#xff09; Apache ka…

数学建模笔记—— 线性规划

数学建模笔记—— 线性规划 线性规划1. 模型引出1.1 线性规划模型的三要素1.2 线性规划模型建立步骤1.3 线性规划的表现形式1.4 线性规划的模型特点 2.典型例题3. python代码求解3.1 求解KK升级的问题3.2 求解投资收益问题 线性规划 在人们的生产实践中&#xff0c;经常会遇到…

Android Studio下载Gradle失败问题解决

问题说明 使用 Android Studio 构建程序报错如下 Could not install Gradle distribution from https://services.gradle.org/distributions/gradle-7.5.1-bin.zip. Reason: java.net.SocketTimeoutException: Connect timed out问题解决 下载对应版本的压缩包 gradle-7.5.1…

系统架构师-ERP+集成

ERP 集成平台end&#xff1a;就懒得画新的页

GEE数据集:加拿大森林生态系统高分辨率年度林地覆盖图(1984-2022 年)

目录 加拿大森林生态系统高分辨率年度林地覆盖图&#xff08;1984-2022 年&#xff09; 简介 数据集说明 空间信息 分类结果 代码 代码链接 引用 许可 网址推荐 0代码在线构建地图应用 机器学习 加拿大森林生态系统高分辨率年度林地覆盖图&#xff08;1984-2022 年&…

0基础跟德姆(dom)一起学AI Python进阶09-算法和数据结构

* 数据结构介绍 * 列表 * 链表 * 算法介绍 * 排序相关(冒泡, 插入, 选择, 快速排序) --- 1.数据结构和算法简介 * 程序 大白话翻译, **程序 数据结构 算法** * 数据结构 指的是 **存储, 组织数据的方式.** * 算法 指的是 **为了解决实际业务问题而思考 思路和方法…

生信圆桌x生信分析平台:助力生物信息学研究的综合工具

介绍 少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 生物信息学的迅速发展催生了众多生信分析平台&#xff0c;这些平台通过集成各种生物信息学工具和算法&#xff0c;极大地简化了数据处理和分析流程&#xff0c;使研究人员能够更高效地…

数据结构基础详解(C语言): 树与二叉树的应用_哈夫曼树与哈夫曼曼编码_并查集_二叉排序树_平衡二叉树

文章目录 树与二叉树的应用1.哈夫曼树与哈夫曼曼编码1.1 带权路径长度1.2 哈夫曼树1.2.1 哈夫曼树的构造1.3 哈夫曼编码 2.并查集2.1 并查集的三要素2.1.1 并查集的逻辑结构2.1.2 并查集的存储结构 2.2 并查集的优化2.2.1 初步优化&#xff08;并操作优化&#xff09;2.2.2 终极…

windows10-VMware17-Ubuntu-22.04-海康2K摄像头兼容问题,求解(已解决)

文章目录 1.webrtc camera测试2.ffmpeg 测试3.Ubuntu 自带相机4.解决办法 环境&#xff1a;windows10系统下&#xff0c;VMware的Ubuntu-22.04系统 问题&#xff1a;摄像头出现兼容问题&#xff0c;本来是想开发测试的&#xff0c;Ubuntu方便些。买了海康2K的USB摄像头&#xf…

NISP 一级 | 2.4 访问控制

关注这个证书的其他相关笔记&#xff1a;NISP 一级 —— 考证笔记合集-CSDN博客 0x01&#xff1a;访问控制基本概念 访问控制是针对越权使用资源的防御措施。 其目标是防止对任何资源&#xff08;如计算资源、通信资源或信息资源&#xff09;进行未授权的访问&#xff0c;从而…

RabbitMQ练习(AMQP 0-9-1 Overview)

1、What is AMQP 0-9-1 AMQP 0-9-1&#xff08;高级消息队列协议&#xff09;是一种网络协议&#xff0c;它允许遵从该协议的客户端&#xff08;Publisher或者Consumer&#xff09;应用程序与遵从该协议的消息中间件代理&#xff08;Broker&#xff0c;如RabbitMQ&#xff09;…

Linux find案例

目录 1. 只查找当前目录&#xff0c;不查找子目录中的指定文件2. 查找到的文件批量复制到指定文件夹中3. 查找到的文件批量修改所属用户和组4. 查找到的文件批量添加执行权限5. 查找到的文件内容全部导入指定文件6. 查找指定目录下指定用户所属的文件7. 获取当前目录下&#xf…

2024年第十五届蓝桥杯青少组国赛撞期GESP认证、放弃那个?

昨天蓝桥杯青少组官网发布了速查|第十五届蓝桥杯大赛青少组省赛成绩查询&#xff0c;首先恭喜2024年蓝桥杯青少组省赛一等奖的同学晋级蓝桥杯大赛青少组国赛&#xff0c;蓝桥杯青少组国赛的时间为2024年9月7日&#xff0c;CCF GESP编程能力等级认证也在同一天开始&#xff0c;同…

《Cloud Native Data Center Networking》(云原生数据中心网络设计)读书笔记 -- 11部署BGP

本章应有助于回答以下问题: 核心的配置概念是什么?如何为 Clos 网络配置 BGP ?无编号的 BGP 如何工作?如何配置 BGP 与主机上的 BGP 发言者 (例如 Kube-router) 建立对等关系?如何配置 BGP 以对网络进行计划维护? 核心的 BGP 配置概念 全局BGP 配置&#xff0c;包含: r…

什么是 TDengine?

TDengine 是一款专为物联网、工业互联网等场景设计并优化的大数据平台&#xff0c;其核心模块是高性能、集群开源、云原生、极简的时序数据库。它能安全高效地将大量设备、数据采集器每天产生的高达 TB 甚至 PB 级的数据进行汇聚、存储、分析和分发&#xff0c;对业务运行状态进…

智能化升级:未来交流充电桩的创新之路

随着电动汽车的普及&#xff0c;交流充电桩作为充电基础设施的重要组成部分&#xff0c;其未来的发展趋势备受关注。本文将探讨交流充电桩在未来可能呈现的几个发展方向。 一、智能化升级 未来的交流充电桩将更加智能化。通过物联网技术&#xff0c;充电桩将能够实现远程监控…

Spring Boot实现文件上传和下载

1.背景 项目中经常会有上传和下载的需求&#xff0c;这篇文章简述一下springboot项目中实现简单的上传和下载。 2.代码工程 实验目标 实现简单的文件上传和下载 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://…