算法之图算法

1、广度优先搜索:

package com.arithmetic.graph;
import java.util.LinkedList;
import java.util.Queue;
//定义一个邻接矩阵用于表示图的结构,0表示两个节点之间没有边,1表示有边连接。
//然后使用一个布尔数组visited来标记节点是否被访问过。
//breadthFirstSearch方法使用广度优先搜索算法遍历图,从指定的起始节点开始。
//使用一个队列queue来存储待访问的节点,首先将起始节点添加到队列中,并将其标记为已访问。
//然后,不断地从队列中取出一个节点并打印它,然后遍历该节点的邻居节点,如果邻居节点还未被访问过,则将其加入队列中,并标记为已访问。
//如此循环,直到队列为空。
//在main方法中,创建一个BreadthFirstSearch对象并调用breadthFirstSearch方法进行测试。
//注意,这只是一个示例,实际应用中可能需要更复杂的数据结构来表示图。
public class BreadthFirstSearchDemo {private int[][] adjacencyMatrix; // 图的邻接矩阵private boolean[] visited; // 用于标记节点是否被访问过public BreadthFirstSearchDemo(int[][] adjacencyMatrix) {this.adjacencyMatrix = adjacencyMatrix;visited = new boolean[adjacencyMatrix.length];}// 广度优先搜索算法public void breadthFirstSearch(int startNode) {Queue<Integer> queue = new LinkedList<>();queue.add(startNode);visited[startNode] = true;while (!queue.isEmpty()) {int currentNode = queue.poll();System.out.print(currentNode + " ");// 遍历当前节点的邻居节点for (int i = 0; i < adjacencyMatrix.length; i++) {if (adjacencyMatrix[currentNode][i] == 1 && !visited[i]) {queue.add(i);visited[i] = true;}}}}public static void main(String[] args) {int[][] adjacencyMatrix = {{0, 1, 1, 0},{1, 0, 0, 1},{1, 0, 0, 1},{0, 1, 1, 0}};BreadthFirstSearchDemo bfs = new BreadthFirstSearchDemo(adjacencyMatrix);System.out.println("BFS traversal starting from node 0:");bfs.breadthFirstSearch(0);}
}

2、深度优先搜索:

package com.arithmetic.graph;
import java.util.Stack;
//使用邻接矩阵来表示图的结构,同时使用布尔数组visited来标记节点是否被访问过。
//depthFirstSearch方法使用深度优先搜索算法遍历图,从指定的起始节点开始。
//使用一个堆栈stack来存储待访问的节点,首先将起始节点压入栈中,并将其标记为已访问。
//然后,不断地从栈中弹出一个节点并打印它,然后遍历该节点的邻居节点,如果邻居节点还未被访问过,则将其压入栈中,并标记为已访问。
//如此循环,直到栈为空。
//在main方法中,创建一个DepthFirstSearch对象并调用depthFirstSearch方法进行测试。
//实际应用中可能需要更复杂的数据结构来表示图。
public class DepthFirstSearchDemo {private int[][] adjacencyMatrix; // 图的邻接矩阵private boolean[] visited; // 用于标记节点是否被访问过public DepthFirstSearchDemo(int[][] adjacencyMatrix) {this.adjacencyMatrix = adjacencyMatrix;visited = new boolean[adjacencyMatrix.length];}// 深度优先搜索算法public void depthFirstSearch(int startNode) {Stack<Integer> stack = new Stack<>();stack.push(startNode);visited[startNode] = true;while (!stack.isEmpty()) {int currentNode = stack.pop();System.out.print(currentNode + " ");// 遍历当前节点的邻居节点for (int i = 0; i < adjacencyMatrix.length; i++) {if (adjacencyMatrix[currentNode][i] == 1 && !visited[i]) {stack.push(i);visited[i] = true;}}}}public static void main(String[] args) {int[][] adjacencyMatrix = {{0, 1, 1, 0},{1, 0, 0, 1},{1, 0, 0, 1},{0, 1, 1, 0}};DepthFirstSearchDemo dfs = new DepthFirstSearchDemo(adjacencyMatrix);System.out.println("DFS traversal starting from node 0:");dfs.depthFirstSearch(0);}
}

3、最短路径算法:

package com.arithmetic.graph;
import java.util.*;
//定义一个 dijkstra 方法来实现Dijkstra算法。
//它接受一个邻接矩阵表示的图和起始节点作为参数,并返回起始节点到其他节点的最短路径数组。
//在 dijkstra 方法中,首先初始化距离数组和访问标记数组。
//然后,使用循环来选择距离最小且未访问的节点,并更新与该节点直接相邻的节点的最短距离。最后,返回最短路径数组。//在主函数中,定义了一个邻接矩阵来表示图,并使用 dijkstra 方法计算起始节点 0 到其他节点的最短路径,并打印结果。
//一个简单示例,实际的实现可能需要更多的错误处理和性能优化。
//还有其他最短路径算法(如Floyd-Warshall算法)的实现方式,可以根据具体的需求选择合适的算法。
public class DijkstraAlgorithmDemo {private static final int INF = Integer.MAX_VALUE; // 代表无穷大的值public int[] dijkstra(int[][] graph, int start) {int n = graph.length;int[] dist = new int[n];boolean[] visited = new boolean[n];Arrays.fill(dist, INF);dist[start] = 0;for (int i = 0; i < n - 1; i++) {int minDist = INF;int minNode = -1;// 选择距离最小且未访问的节点for (int j = 0; j < n; j++) {if (!visited[j] && dist[j] < minDist) {minDist = dist[j];minNode = j;}}visited[minNode] = true;// 更新与当前节点直接相邻的节点的最短距离for (int j = 0; j < n; j++) {if (!visited[j] && graph[minNode][j] != INF && dist[minNode] + graph[minNode][j] < dist[j]) {dist[j] = dist[minNode] + graph[minNode][j];}}}return dist;}public static void main(String[] args) {int[][] graph = {{0, 3, INF, 7},{3, 0, 2, INF},{INF, 2, 0, 1},{7, INF, 1, 0}};DijkstraAlgorithmDemo dijkstra = new DijkstraAlgorithmDemo();int[] dist = dijkstra.dijkstra(graph, 0);System.out.println("最短路径:");for (int i = 0; i < dist.length; i++) {System.out.println("0 -> " + i + ": " + dist[i]);}}
}

4、贪心算法:

package com.arithmetic.graph;import java.util.Arrays;
//贪心算法
//在给定硬币面额的情况下,找零钱的最少数量。
//先将硬币面额按照升序进行排序,然后从最大面额的硬币开始,选择尽可能多的该面额硬币进行找零,直到目标金额为0。
//最后返回找到的硬币数量。
public class GreedyAlgorithmDemo {public static int findMinCoins(int[] coins, int amount) {Arrays.sort(coins); // 将硬币面额按照升序排序int count = 0;for (int i = coins.length - 1; i >= 0; i--) {while (amount >= coins[i]) { // 当目标金额大于等于当前面额时amount -= coins[i]; // 目标金额减去当前面额count++; // 零钱数量加1}}return count;}public static void main(String[] args) {int[] coins = {1, 5, 10, 25}; // 面额为1、5、10、25的硬币int amount = 36; // 目标金额int minCoins = findMinCoins(coins, amount);System.out.println("最少需要的硬币数量为:" + minCoins);}
}

5、最小生成树算法1:

package com.arithmetic.graph;
import java.util.*;
//最小生成树算法用于在一个连通的无向加权图中,找到一个权重和最小的生成树(包含所有顶点且没有环)。
//在KruskalMSTDemo 中,使用Kruskal算法来查找最小生成树的权重。
//在这种算法中,需要提供一个图的表示以及图中各个边的权重。
//在主函数中,定义一个图的表示以及图中各个边的权重,并调用相应的算法来查找最小生成树的权重。
public class KruskalMSTDemo {class Edge implements Comparable<Edge> {int src, dest, weight;public int compareTo(Edge compareEdge) {return this.weight - compareEdge.weight;}};private int V, E; // 图的顶点数和边数private Edge[] edges; // 图的所有边public KruskalMSTDemo(int V, int E) {this.V = V;this.E = E;edges = new Edge[E];for (int i = 0; i < E; i++) {edges[i] = new Edge();}}private int find(int[] parent, int i) {if (parent[i] == -1) {return i;}return find(parent, parent[i]);}private void union(int[] parent, int x, int y) {int xset = find(parent, x);int yset = find(parent, y);parent[xset] = yset;}public void kruskalMST() {Edge[] result = new Edge[V];int e = 0;int i = 0;for (i = 0; i < V; i++) {result[i] = new Edge();}Arrays.sort(edges);int[] parent = new int[V];Arrays.fill(parent, -1);i = 0;while (e < V-1) {Edge nextEdge = edges[i++];int x = find(parent, nextEdge.src);int y = find(parent, nextEdge.dest);if (x != y) {result[e++] = nextEdge;union(parent, x, y);}}printMST(result);}private void printMST(Edge[] result) {System.out.println("Edge   Weight");for (int i = 0; i < V-1; i++) {System.out.println(result[i].src + " - " + result[i].dest + "    " + result[i].weight);}}public static void main(String[] args) {int V = 5; // 图的顶点数int E = 7; // 图的边数KruskalMSTDemo mst = new KruskalMSTDemo(V, E);mst.edges[0].src = 0;mst.edges[0].dest = 1;mst.edges[0].weight = 7;mst.edges[1].src = 0;mst.edges[1].dest = 3;mst.edges[1].weight = 5;mst.edges[2].src = 1;mst.edges[2].dest = 2;mst.edges[2].weight = 8;mst.edges[3].src = 1;mst.edges[3].dest = 3;mst.edges[3].weight = 9;mst.edges[4].src = 1;mst.edges[4].dest = 4;mst.edges[4].weight = 7;mst.edges[5].src = 2;mst.edges[5].dest = 4;mst.edges[5].weight = 5;mst.edges[6].src = 3;mst.edges[6].dest = 4;mst.edges[6].weight = 15;mst.kruskalMST();}
}

6、最小生成树算法2:

package com.arithmetic.graph;
import java.util.*;
//最小生成树算法用于在一个连通的无向加权图中,找到一个权重和最小的生成树(包含所有顶点且没有环)。
//在PrimMSTDemo中,使用Prim算法来查找最小生成树的权重。
//在这种算法中,需要提供一个图的表示以及图中各个边的权重。
//在主函数中,定义一个图的表示以及图中各个边的权重,并调用相应的算法来查找最小生成树的权重。
public class PrimMSTDemo {private int V; // 图的顶点数private int[] parent; // 最小生成树的父节点数组private boolean[] visited; // 记录顶点是否被访问过private int[][] graph; // 图的邻接矩阵表示public PrimMSTDemo(int[][] graph) {this.V = graph.length;this.graph = graph;parent = new int[V];visited = new boolean[V];for (int i = 0; i < V; i++) {parent[i] = -1;visited[i] = false;}}public void primMST() {int[] key = new int[V]; // 记录顶点到最小生成树的最小权值Arrays.fill(key, Integer.MAX_VALUE);key[0] = 0;for (int count = 0; count < V-1; count++) {int u = minKey(key, visited);visited[u] = true;for (int v = 0; v < V; v++) {if (graph[u][v] != 0 && !visited[v] && graph[u][v] < key[v]) {parent[v] = u;key[v] = graph[u][v];}}}printMST();}private int minKey(int[] key, boolean[] visited) {int min = Integer.MAX_VALUE;int minIndex = -1;for (int v = 0; v < V; v++) {if (!visited[v] && key[v] < min) {min = key[v];minIndex = v;}}return minIndex;}private void printMST() {System.out.println("Edge   Weight");for (int i = 1; i < V; i++) {System.out.println(parent[i] + " - " + i + "    " + graph[i][parent[i]]);}}public static void main(String[] args) {int[][] graph = {{0, 2, 0, 6, 0},{2, 0, 3, 8, 5},{0, 3, 0, 0, 7},{6, 8, 0, 0, 9},{0, 5, 7, 9, 0}};PrimMSTDemo mst = new PrimMSTDemo(graph);mst.primMST();}
}

7、最小生成树算法3:

package com.arithmetic.graph;
import java.util.*;
//最小生成树算法用于在一个连通的无向加权图中,找到一个权重和最小的生成树(包含所有顶点且没有环)。
//在PrimAlgorithmDemo 中,使用Prim算法来查找最小生成树的总权重。
//在这种算法中,需要提供一个图的表示以及图中各个边的权重。
//在主函数中,定义一个图的表示以及图中各个边的权重,并调用相应的算法来查找最小生成树的总权重。//最小生成树算法可以用来构建网络通信中的最优拓扑结构,以便实现最小的传输代价或者最小的延迟。
//在铁路规划中,可以用来确定线路间的最优连接方式,以便降低建设成本、减少运输时间.
//在石油、天然气、水等管道系统的布线中,可以帮助确定最优的管道连接方式,以减少材料和能耗成本。
//在电力传输网络中,可以帮助确定电力线路的最佳布局,以最小化能源损耗和传输成本。
//在交通规划中,可以用来确定交通网络中的最优路径,以减少交通拥堵和减少行车时间。
//在电路设计中,可以用来确定元器件之间的连接方式,以降低电路的复杂度和成本。
//在城市规划中,可以用来确定街道和道路的布局,以最小化交通拥堵和提高城市运行效率。class PrimAlgorithmDemo {public int prim(int[][] graph) {int n = graph.length;int[] dist = new int[n];boolean[] visited = new boolean[n];Arrays.fill(dist, Integer.MAX_VALUE);dist[0] = 0;int minWeight = 0;for (int i = 0; i < n; i++) {int u = -1;for (int j = 0; j < n; j++) {if (!visited[j] && (u == -1 || dist[j] < dist[u])) {u = j;}}visited[u] = true;minWeight += dist[u];for (int j = 0; j < n; j++) {if (!visited[j] && graph[u][j] != 0 && graph[u][j] < dist[j]) {dist[j] = graph[u][j];}}}return minWeight;}public static void main(String[] args) {int[][] graph = {{0, 2, 0, 6, 0},{2, 0, 3, 8, 5},{0, 3, 0, 0, 7},{6, 8, 0, 0, 9},{0, 5, 7, 9, 0}};PrimAlgorithmDemo prim = new PrimAlgorithmDemo();int minWeight = prim.prim(graph);System.out.println("最小生成树的总权重: " + minWeight);}
}

 

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

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

相关文章

keep-alive包裹的两个页面使用了echart,在resize后切换,echart会出现空白现象,需要再resize才会出现

问题&#xff1a;页面有2个echarts图&#xff0c;一打开页面图表是有的&#xff0c;然后切换到另一个页面&#xff0c;也是有2个echarts图&#xff0c;然后缩放浏览器窗口&#xff0c;再切换回第一次打开的页面&#xff0c;图表不显示。 因为keep-live保存了当前页面的属性&am…

Knife4j的配置

要使用Knife4j&#xff0c;需要进行以下配置步骤&#xff1a; 在pom.xml文件中添加依赖&#xff1a; <!-- Knife4j --> <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><v…

Linux 学习之路 - 进程篇 - PCB介绍1-标识符

目录 一、基础的命令 <1> ps axj 命令 <2> top 命令 <3> proc 目录 二、进程的标识符 <1>范围 <2>如何获取标识符 <3>bash进程 三、创建进程 一、基础的命令 前面介绍了那么多&#xff0c;但是我们没有观察到进程相关状态&#x…

js把数组中的某些项移动到前面,使用sort函数

在JavaScript中&#xff0c;使用sort函数可以按照特定的规则对数组进行排序。如果你想根据特定的条件把数组中的某些项移动到前面&#xff0c;你可以使用sort函数来实现这一点。以下是一个例子&#xff0c;演示了如何使用sort函数把满足特定条件的数组项移动到数组的前面&#…

机器人码垛机的技术特点与应用

随着科技的飞速发展&#xff0c;机器人技术正逐渐渗透到各个行业领域&#xff0c;其中&#xff0c;机器人码垛机在物流行业的应用尤为引人瞩目。它不仅提高了物流效率&#xff0c;降低了成本&#xff0c;更在改变传统物流模式的同时&#xff0c;为行业发展带来了重大的变革。 一…

MQ死信队列:面试题

所谓的死信队列只不过是我们自己定义的一个队列&#xff0c;注意对于这个队列只能人工干预 面试题&#xff1a;你们是如何保证消息不会丢失的 1&#xff0c;什么是死信 在RabitMQ中充当主角的就是消息&#xff0c;在不同场景下&#xff0c;消息会有不同地表现。 死信就是在…

python蓝桥杯选数

文章目录 前言一、题意二、代码1.代码的实现2.读入数据 总结 前言 本题涉及到很多python中的知识点&#xff0c;比如combinations&#xff08;列表的组合&#xff09;应用&#xff0c;以及素数的判断 一、题意 已知 n 个整数 x1,x2,…,xn,以及一个整数 k&#xff08;k&#x…

SQL 批量替换表中某一列字段的值

现有客户数据如下&#xff0c;需要将表 t_109_original&#xff0c;中的FILE_PATH 字段里面值含 P9_3 全部替换为 P9_4 FILE_SIZEFILE_PATHFILE_NAME167376P9_3/original/12/109/35/0/35.jpg0103-Y-.DJ.G-第1号-0001-001-0002.jpg169230P9_3/original/12/109/36/0/36.jpg0103-…

SpringBoot学习笔记三-原理分析

SpringBoot学习笔记三-原理分析 SpringBoot自动装配1.1 案例1.2 通过注解方式管理Bean1.3 小结1.4 Enable注解1.5 Import注解1.5.1 ImportSelector实现类1.5.2 导入ImportBeanDefinitionRegistrar 1.5 EnableAutoConfiguration1.6 案例 SpringBoot自动装配 当再pom.xml中导入对…

活动发布会新闻通稿如何写?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 撰写活动发布会的新闻通稿需要遵循一定的结构和内容要点&#xff0c;以确保信息的准确性、完整性和吸引力。以下是撰写活动发布会新闻通稿的基本步骤和建议&#xff1a; 标题&#xff1…

【智能算法】长鼻浣熊优化算法(COA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2023年&#xff0c;M Dehghani等人受到长鼻浣熊自然行为启发&#xff0c;提出了长鼻浣熊优化算法&#xff08;Coati Optimization Algorithm&#xff0c;COA&#xff09;。 2.算法原理 2.1算法思想…

C语言 函数——函数封装与程序的健壮性

目录 函数封装&#xff08;Encapsulation&#xff09; 如何增强程序的健壮性&#xff1f; 如何保证不会传入负数实参&#xff1f; 函数设计的基本原则 函数封装&#xff08;Encapsulation&#xff09; 外界对函数的影响——仅限于入口参数 函数对外界的影响——仅限于一个…

C++:内联函数inline,auto关键字,基于范围的for循环,nullpter

文章目录 1.内联函数 inline1.1 概念1.2查看方法1.3 特性1.4 题外话&#xff1a;宏 2.auto关键字2.1 auto 简介2.2 auto使用细则 3. 基于范围的for循环4. nullpter 1.内联函数 inline 1.1 概念 inline int Add(int x, int y) {return x y; } int main(){int ret 0;ret Add…

vim的一些查找及修改操作

:s/foo/bar/gc&#xff1a;在行中查找 foo 并询问是否替换为 bar。 :v/pattern/d&#xff1a;删除所有不匹配 pattern 的行。 :g/pattern/d&#xff1a;删除所有匹配 pattern 的行。 :g/pattern/s/foo/bar/g&#xff1a;在匹配 pattern 的行中&#xff0c;将 foo 替换为 bar。…

Etcd 故障节点修复

etcd: 3.3.11 查询出故障的节点 在正常节点上操作 export ETCDCTL_API=3 etcdctl --endpoints http://192.168.56.100:2379,http://192.168.56.101:2379 member list --write-out="table"export ETCDCTL_API=3 etcdctl --endpoints http://192.168.56.100:2379,htt…

Vue input密码输入框自定义密码眼睛icon

我们用的饿了么UI组件库里,密码输入框的icon是固定不变的,如下所示: 点击"眼睛"这个icon不变,现在需求是UI给的设计稿里,密码输入框的"眼睛"有如下两种: 代码如下: <el-input:key="passwordType"ref="password"

重装系统前备份笔记

一、点查看自定义快捷键可以定义一些快速启动方式 然后用不习惯的快捷键也能在这里改 二、android studio 快捷键导出备份 导入方法&#xff1a; android studio &#xff0d;>file->import setting ->选择jar包即可 导出studio的设置方法&#xff1a; android …

vite项目如何安装element

创建vitevue3项目 npm create vitelatest安装element包 # 选择一个你喜欢的包管理器# NPM $ npm install element-plus --save# Yarn $ yarn add element-plus# pnpm $ pnpm install element-plus创建和挂载Vue应用 1. 完整导入 直接挂载就完了。 // main.ts import { cre…

假期别闲着:REST API实战演练之创建Rest API

1、创建实体类&#xff0c;模拟实体对象 创建一个类&#xff0c;模拟数据数据库来存储数据&#xff0c;这个类就叫Person。 其代码如下&#xff1a; package com.restful;public class Person {private String name;private String about;private int birthYear;public Perso…

【jQuery】jQuery框架

目录 1.jQuery基本用法 1.1选择器 1.2jQuery对象 1.3事件绑定 1.4链式编程 1.5过滤方法 1.6样式操纵 1.6属性操纵 1.7操作value 1.8查找方法 1.9类名操纵 1.10事件进阶 1.11触发事件 1.12window事件绑定 2.节点操作与动画 2.1获取位置 2.2滚动距离 2.3显示/隐…