算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法

简介: 这篇文章介绍了基于贪婪技术思想的Prim算法和Dijkstra算法,包括它们的伪代码描述、Java源代码实现、时间效率分析,并展示了算法的测试用例结果,使读者对贪婪技术及其应用有了更深入的理解。

一、名称

动态规划法应用

二、目的

1.贪婪技术的基本思想;
2.学会运用贪婪技术解决实际设计应用中碰到的问题。

三、要求

1.实现基于贪婪技术思想的Prim算法;
2.实现基于贪婪技术思想的Dijkstra算法。

四、内容

1.实现基于贪婪技术思想的Prim算法

1.1、Prim算法的伪代码描述

算法 Prim(G)
//构造最小生成树的Prim算法
//输入:加权连通图G<V,E>
//输出:E(T),组成G的最小生成树的边的集合
V(t)←{V0}  //可以用任意顶点来初始化树的顶点集合
Er←◎(集合空)
  For i←1 to |V|-1 do
在所有的边(v,u)中,求权重最小的边e*=(v*,u*),
使得v在Vt中而V-Vt中
V←VtU{u*}
Et←ErU{e*}
Return Er

2.2、Prim算法的源代码实现


package com.zyz.four;

import java.util.*;

public class Primel {
    static int MAX = Integer.MAX_VALUE;

    public static void main(String[] args) {
        int[][] map = new int[][]{
                {0, 10, MAX, MAX, MAX, 11, MAX, MAX, MAX},
                {10, 0, 18, MAX, MAX, MAX, 16, MAX, 12},
                {MAX, MAX, 0, 22, MAX, MAX, MAX, MAX, 8},
                {MAX, MAX, 22, 0, 20, MAX, MAX, 16, 21},
                {MAX, MAX, MAX, 20, 0, 26, MAX, 7, MAX},
                {11, MAX, MAX, MAX, 26, 0, 17, MAX, MAX},
                {MAX, 16, MAX, MAX, MAX, 17, 0, 19, MAX},
                {MAX, MAX, MAX, 16, 7, MAX, 19, 0, MAX},
                {MAX, 12, 8, 21, MAX, MAX, MAX, MAX, 0}};
        prim(map, map.length);
    }

    public static void prim(int[][] graph, int n) {

        char[] c = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'E', 'F'};
        int[] lowcost = new int[n];  //到新集合的最小权
        int[] mid = new int[n];//存取前驱结点
        List<Character> list = new ArrayList<Character>();//用来存储加入结点的顺序
        int i, j, min, minid, sum = 0;
        //初始化辅助数组
        for (i = 1; i < n; i++) {
            lowcost[i] = graph[0][i];
            mid[i] = 0;
        }
        list.add(c[0]);
        //一共需要加入n-1个点
        for (i = 1; i < n; i++) {
            min = MAX;
            minid = 0;
            //每次找到距离集合最近的点
            for (j = 1; j < n; j++) {
                if (lowcost[j] != 0 && lowcost[j] < min) {
                    min = lowcost[j];
                    minid = j;
                }
            }

            if (minid == 0) return;
            list.add(c[minid]);
            lowcost[minid] = 0;
            sum += min;
            System.out.println(c[mid[minid]] + "到" + c[minid] + " 权值:" + min);
            //加入该点后,更新其它点到集合的距离
            for (j = 1; j < n; j++) {
                if (lowcost[j] != 0 && lowcost[j] > graph[minid][j]) {
                    lowcost[j] = graph[minid][j];
                    mid[j] = minid;
                }
            }
        }
        System.out.println("sum:" + sum);

    }

}

2.3、Prim算法的时间效率分析

时间效率:Tn=O(n*n),在每一遍|V|-1次迭代中,就要遍历实现优先队列的数组,来查找并删除距离最小的顶点,如果有必要,在更新余下顶点的优先级。

2.实现基于贪婪技术思想的Dijkstra算法

2.1、Dijkstra算法的伪代码描述

算法 Dijkstra(G,s)
//单起点最短路径的Dijkstra算法
//输入:具非权重加权连通图G=<V,E>以及它的顶点s
//输出:对于V中的每个顶点v来说,从s到v的最短路径的长度d
//以及路径上的倒数第二个顶点Pv
Initialize(Q)//将顶点优先从队列初始化为空
For V中每一个顶点v
  dr←无穷大;Pv←null
insert(Q,v,dv)//初始化优先队列中顶点的优先级
ds←0;Decrease(Q,s,ds)//将s的优先级更新为ds
V(r) ←空集

For i←0 to |V|-1 do
  u* ←DeleteMin(Q) //删除优先级最小的元素
Vr←VrU{u*}
   For V-Vr中每一个和u*相邻的顶点u do
if du*+w(u*,u)<du
  du←du*+w(u*,u);pu du*+w(u*,u)u*
Decrease(Q,u,du)

2.2、Dijkstra算法的源代码实现

package com.zyz.four;

public class Dijkstra {
    /*
     * 参数adjMatrix:为图的权重矩阵,权值为-1的两个顶点表示不能直接相连
     * 函数功能:返回顶点0到其它所有顶点的最短距离,其中顶点0到顶点0的最短距离为0
     */
    public int[] getShortestPaths(int[][] adjMatrix) {
        int[] result = new int[adjMatrix.length];   //用于存放顶点0到其它顶点的最短距离
        boolean[] used = new boolean[adjMatrix.length];  //用于判断顶点是否被遍历
        used[0] = true;  //表示顶点0已被遍历
        for(int i = 1;i < adjMatrix.length;i++) {
            result[i] = adjMatrix[0][i];
            used[i] = false;
        }

        for(int i = 1;i < adjMatrix.length;i++) {
            int min = Integer.MAX_VALUE;    //用于暂时存放顶点0到i的最短距离,初始化为Integer型最大值
            int k = 0;
            for(int j = 1;j < adjMatrix.length;j++) {  //找到顶点0到其它顶点中距离最小的一个顶点
                if(!used[j] && result[j] != -1 && min > result[j]) {
                    min = result[j];
                    k = j;
                }
            }
            used[k] = true;    //将距离最小的顶点,记为已遍历
            for(int j = 1;j < adjMatrix.length;j++) {  //然后,将顶点0到其它顶点的距离与加入中间顶点k之后的距离进行比较,更新最短距离
                if(!used[j]) {  //当顶点j未被遍历时
                    //首先,顶点k到顶点j要能通行;这时,当顶点0到顶点j的距离大于顶点0到k再到j的距离或者顶点0无法直接到达顶点j时,更新顶点0到顶点j的最短距离
                    if(adjMatrix[k][j] != -1 && (result[j] > min + adjMatrix[k][j] || result[j] == -1))
                        result[j] = min + adjMatrix[k][j];
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {
        Dijkstra test = new Dijkstra();
        int[][] adjMatrix = {
  
  {0,6,3,-1,-1,-1},
                {6,0,2,5,-1,-1},
                {3,2,0,3,4,-1},
                {-1,5,3,0,2,3},
                {-1,-1,4,2,0,5},
                {-1,-1,-1,3,5,0}};
        int[] result = test.getShortestPaths(adjMatrix);
        System.out.println("顶点0到图中所有顶点之间的最短距离为:");
        for(int i = 0;i < result.length;i++)
            System.out.print(result[i]+" ");
    }
}

2.3、Dijkstra算法的时间效率分析

Dijkstra复杂度是O(N^2),用权重矩阵表示,优先队列用无序数组来实现。

3、运行结果

3.1、Dijkstra算法的测试用例结果截图

在这里插入图片描述

3.2、Prim算法的测试用例结果截图

在这里插入图片描述

4、小结

在实验的过程中,我对贪婪技术的基本思想有了更加深入的了解。学会使用动态规划的目的,将问题从小的方面开始解决,逐步向解决整个问题靠近。通过本次实验、我了解到基于贪婪技术思想的Prim算法、Dijkstra算法基本原理。掌握了基本的使用方法、能够运用这种思路解决生活中的实际问题。

相关文章
|
3月前
|
人工智能 运维 算法
基于 C# 深度优先搜索算法的局域网集中管理软件技术剖析
现代化办公环境中,局域网集中管理软件是保障企业网络高效运行、实现资源合理分配以及强化信息安全管控的核心工具。此类软件需应对复杂的网络拓扑结构、海量的设备信息及多样化的用户操作,而数据结构与算法正是支撑其强大功能的基石。本文将深入剖析深度优先搜索(Depth-First Search,DFS)算法,并结合 C# 语言特性,详细阐述其在局域网集中管理软件中的应用与实现。
85 3
|
4月前
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
119 15
|
4月前
|
分布式计算 并行计算 算法
MapReduce在实现PageRank算法中的应用
总结来说,在实现PageRank算法时使用MapReduce能够有效地进行大规模并行计算,并且具有良好的容错性和可扩展性。
182 76
|
2月前
|
监控 算法 JavaScript
基于 JavaScript 图算法的局域网网络访问控制模型构建及局域网禁止上网软件的技术实现路径研究
本文探讨局域网网络访问控制软件的技术框架,将其核心功能映射为图论模型,通过节点与边表示终端设备及访问关系。以JavaScript实现DFS算法,模拟访问权限判断,优化动态策略更新与多层级访问控制。结合流量监控数据,提升网络安全响应能力,为企业自主研发提供理论支持,推动智能化演进,助力数字化管理。
69 4
|
2月前
|
监控 算法 JavaScript
公司局域网管理视域下 Node.js 图算法的深度应用研究:拓扑结构建模与流量优化策略探析
本文探讨了图论算法在公司局域网管理中的应用,针对设备互联复杂、流量调度低效及安全监控困难等问题,提出基于图论的解决方案。通过节点与边建模局域网拓扑结构,利用DFS/BFS实现设备快速发现,Dijkstra算法优化流量路径,社区检测算法识别安全风险。结合WorkWin软件实例,展示了算法在设备管理、流量调度与安全监控中的价值,为智能化局域网管理提供了理论与实践指导。
88 3
|
2月前
|
存储 监控 算法
内网监控桌面与 PHP 哈希算法:从数据追踪到行为审计的技术解析
本文探讨了内网监控桌面系统的技术需求与数据结构选型,重点分析了哈希算法在企业内网安全管理中的应用。通过PHP语言实现的SHA-256算法,可有效支持软件准入控制、数据传输审计及操作日志存证等功能。文章还介绍了性能优化策略(如分块哈希计算和并行处理)与安全增强措施(如盐值强化和动态更新),并展望了哈希算法在图像处理、网络流量分析等领域的扩展应用。最终强调了构建完整内网安全闭环的重要性,为企业数字资产保护提供技术支撑。
86 2
|
2月前
|
存储 监控 算法
基于 C# 时间轮算法的控制局域网上网时间与实践应用
在数字化办公与教育环境中,局域网作为内部网络通信的核心基础设施,其精细化管理水平直接影响网络资源的合理配置与使用效能。对局域网用户上网时间的有效管控,已成为企业、教育机构等组织的重要管理需求。这一需求不仅旨在提升员工工作效率、规范学生网络使用行为,更是优化网络带宽资源分配的关键举措。时间轮算法作为一种经典的定时任务管理机制,在局域网用户上网时间管控场景中展现出显著的技术优势。本文将系统阐述时间轮算法的核心原理,并基于 C# 编程语言提供具体实现方案,以期深入剖析该算法在局域网管理中的应用逻辑与实践价值。
61 5
|
3月前
|
机器学习/深度学习 存储 算法
18个常用的强化学习算法整理:从基础方法到高级模型的理论技术与代码实现
本文系统讲解从基本强化学习方法到高级技术(如PPO、A3C、PlaNet等)的实现原理与编码过程,旨在通过理论结合代码的方式,构建对强化学习算法的全面理解。
190 10
18个常用的强化学习算法整理:从基础方法到高级模型的理论技术与代码实现
|
2月前
|
存储 机器学习/深度学习 算法
论上网限制软件中 Python 动态衰减权重算法于行为管控领域的创新性应用
在网络安全与行为管理的学术语境中,上网限制软件面临着精准识别并管控用户不合规网络请求的复杂任务。传统的基于静态规则库或固定阈值的策略,在实践中暴露出较高的误判率与较差的动态适应性。本研究引入一种基于 “动态衰减权重算法” 的优化策略,融合时间序列分析与权重衰减机制,旨在显著提升上网限制软件的实时决策效能。
72 2

热门文章

最新文章