算法设计(动态规划应用实验报告)实现基于贪婪技术思想的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算法基本原理。掌握了基本的使用方法、能够运用这种思路解决生活中的实际问题。

相关文章
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
【自然语言处理】TF-IDF算法在人工智能方面的应用,附带代码
TF-IDF算法在人工智能领域,特别是自然语言处理(NLP)和信息检索中,被广泛用于特征提取和文本表示。以下是一个使用Python的scikit-learn库实现TF-IDF算法的简单示例,并展示如何将其应用于文本数据。
212 65
|
2月前
|
存储 人工智能 自然语言处理
算法、系统和应用,三个视角全面读懂混合专家(MoE)
【8月更文挑战第17天】在AI领域,混合专家(MoE)模型以其独特结构成为推动大型语言模型发展的关键技术。MoE通过动态选择专家网络处理输入,实现条件计算。稀疏型MoE仅激活部分专家以减少计算负担;软MoE则加权合并专家输出提升模型稳定性。系统层面,MoE优化计算、通信与存储,利用并行化策略提高效率。在NLP、CV、推荐系统等领域展现强大应用潜力,但仍面临训练稳定性、可解释性等挑战。[论文链接: https://arxiv.org/pdf/2407.06204]
187 63
|
5天前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的优化算法及其应用
本文旨在探讨深度学习中常用的优化算法,包括梯度下降、动量方法、AdaGrad、RMSProp和Adam等。通过分析每种算法的原理、优缺点及适用场景,揭示它们在训练深度神经网络过程中的关键作用。同时,结合具体实例展示这些优化算法在实际应用中的效果,为读者提供选择合适优化算法的参考依据。
|
6天前
|
算法 前端开发 机器人
一文了解分而治之和动态规则算法在前端中的应用
该文章详细介绍了分而治之策略和动态规划算法在前端开发中的应用,并通过具体的例子和LeetCode题目解析来说明这两种算法的特点及使用场景。
一文了解分而治之和动态规则算法在前端中的应用
|
12天前
|
算法 调度
贪心算法基本概念与应用场景
尽管贪心算法在许多问题中都非常有效,但它并不总是会产生最优解。因此,在应用贪心算法前,重要的是先分析问题是否适合采用贪心策略。一些问题可能需要通过动态规划或回溯等其他算法来解决,以找到确切的全局最优解。
44 1
WK
|
15天前
|
机器学习/深度学习 算法 数据挖掘
PSO算法的应用场景有哪些
粒子群优化算法(PSO)因其实现简单、高效灵活,在众多领域广泛应用。其主要场景包括:神经网络训练、工程设计、电力系统经济调度与配电网络重构、数据挖掘中的聚类与分类、控制工程中的参数整定、机器人路径规划、图像处理、生物信息学及物流配送和交通管理等。PSO能处理复杂优化问题,快速找到全局最优解或近似解,展现出强大的应用潜力。
WK
18 1
|
24天前
|
机器学习/深度学习 算法 Python
群智能算法:深入解读人工水母算法:原理、实现与应用
近年来,受自然界生物行为启发的优化算法备受关注。人工水母算法(AJSA)模拟水母在海洋中寻找食物的行为,是一种新颖的优化技术。本文详细解读其原理及实现步骤,并提供代码示例,帮助读者理解这一算法。在多模态、非线性优化问题中,AJSA表现出色,具有广泛应用前景。
|
2月前
|
缓存 算法 Java
刷算法,你应该知道的队列经典应用
文章介绍了队列的基本特性和经典应用,包括如何用队列实现栈、使用优先级队列解决Top K问题,并通过LeetCode题目示例展示了队列在算法实现中的应用。
刷算法,你应该知道的队列经典应用
|
6天前
|
算法 前端开发
一文了解贪心算法和回溯算法在前端中的应用
该文章深入讲解了贪心算法与回溯算法的原理及其在前端开发中的具体应用,并通过分析LeetCode题目来展示这两种算法的解题思路与实现方法。
|
1月前
|
机器学习/深度学习 算法 数据挖掘
R语言中的支持向量机(SVM)与K最近邻(KNN)算法实现与应用
【9月更文挑战第2天】无论是支持向量机还是K最近邻算法,都是机器学习中非常重要的分类算法。它们在R语言中的实现相对简单,但各有其优缺点和适用场景。在实际应用中,应根据数据的特性、任务的需求以及计算资源的限制来选择合适的算法。通过不断地实践和探索,我们可以更好地掌握这些算法并应用到实际的数据分析和机器学习任务中。
下一篇
无影云桌面