首页 > 编程语言 >算法分析与设计学习总结_1

算法分析与设计学习总结_1

时间:2024-01-20 17:38:25浏览次数:33  
标签:总结 递归 int 复杂性 学习 算法 顶点 贪心

算法分析与设计

一、算法概述

1.1算法和过程

(1)算法和过程都是解决问题的一种方法的逐步描述

(2) 他们都是由若干条指令组成的有穷序列;每条指令意义确定;具有零个或多个输入;产生若干个输出。

(3) 算法的执行时间是有限的(终止性);过程的执行时间可能是无限的。

1.2算法

(1)程序和算法

​ ① 程序是某个算法 / 过程 在计算机上的具体实现;程序依赖于程序设计语言,甚至依赖于计算机结构。

​ ② 算法是脱离具体的计算机结构和程序设计语言的。

(3)算法的复杂性:算法运行时所需要的计算机资源的量多少。(所需资源量越多则复杂性越高,反之所需资源量越少则复杂性越低)

​ ① 时间复杂性:需要时间的资源量;空间复杂性: 需要空间的资源量。

​ ② 决定算法复杂性的因素:求解问题的规模;具体的输入数据;算法本身的设计。

二、递归和分治

2.1递归

(1)递归概念

​ ① 递归算法 P = if B then Q else β(S, P) 其中,B为递归终止条件,S和Q都不包含P。

​ ② 递归算法的思想:将对较大规模对象的操作归结于对较小规模对象实施同样的操作。

​ ③ 递归元: 递归算法的变元。递归元的变化在递归定义中定义,它的变化能导致递归算法的终止。

(2)汉诺塔问题

void Hanoi(int n, int Fr, int To, int As)
       {
             if  (n > 0) {
                Hanoi(n–1, Fro, Ass, To);
                Move(Fro, To);
                Hanoi(n–1, Ass, To, Fro)}
        }

​ ① 汉诺塔问题的时间复杂性为 O(2n)

(3)常见递归形式

  • 多变元递归:递归元多于一个的递归

    /*
    整数划分问题:将一个正整数n表示为一系列正整数之和,
    n = n1 + n2 +…+nk,其中n1≥n2≥…≥nk≥1, k≥1
    (例如ρ(6) = 11,即整数6的划分数为11:
        6, 5+1, 4+2, 4+1+1,  3+3, 3+2+1, 3+1+1+1
        2+2+2, 2+2+1+1, 2+1+1+1+1, 
        1+1+1+1+1+1 )
    */
    q(n, m) { 
           if (n < 1) || (m < 1)      return 0;
           if (n == 1) || (m == 1)  return 1;
           if (n == 1) || (n < m)    return 1 + q(n, n–1);
           return q(n, m–1) + q(n–m, m);  }
    //整数n的划分数ρ(n) = q(n, n)	
    
  • 多步递归:递归函数f(x, y),其中y是递归元,不仅与f(x, y–1)有关,而且与f(x, y–2),……,乃至f(x, 0)有关。(Fibonacci函数)

    QQ图片20231225135217

  • 嵌套递归:递归调用中又含有递归调用,又称为多重递归

    QQ图片20231225135418

  • 联立递归:同时定义几个函数,它们彼此相互调用,从而形成递归,又称间接递归。

    QQ图片20231225135516

    (4)递归算法的时间复杂性

    ​ ① 递归元的递减方式:减法(n - b)和除法(n / b)

    ​ ② 递归时间复杂性的递归方程:

    QQ图片20231225161516

    ​ ③ 当递减方式为 n-- 时,时间复杂性T(n) = O(an)

2.2分治法

(1)分治法

​ ① 分治法基本思想:n将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。递归地解这些问题,然后将各个子问题的解合并在一起,从而得到原问题的解。

​ ② 分治法的一般算法模式

Divide-and-Conquer(P)
{//|P|<=n0表示P的规模不超过阈值n0,可直接求解
    if (|P|<=n0) return Adhoc(P);
   divide P into smaller subinstants P1, .., Pk;
   for (i =1; i <= k; i++) 
         yi = Divide-and-Conquer(Pi);
   return Merge(y1, …, yk);
} //算法Merge(y1, …, yk)表示将子问题的解合成P的解

​ ③ 二分搜索的算法复杂度:logn+1;时间复杂度:O( logn )。

​ ④ 分治法复杂度低于原问题,但是整体上能否降低复杂性还取决于合并。通过降低合并复杂性可以降低原问题求解的复杂性。

(2)大整数的乘法

(3)棋盘覆盖问题

三、贪心算法

3.1贪心算法

(1)贪心算法

​ ① 基本思想:贪心算法每次选择目前最优的解,即通过一系列局部最优来获得整体最优。

​ ② 贪心算法的基本要素:贪心选择性质。(指所求问题的整体最优解可以通过一系列局部最优解的选择,即贪心选择来达到。)

​ ③ 贪心算法通常以自顶向下的方式进行,每次贪心选择就将原问题转化为规模更小的子问题。

(2)单源最短路径问题

​ ① 贪心选择策略:选择从源v出发目前用最短的路径所到达的顶点,这就是目前的局部最优解。

​ ② 贪心基本思想:首先设置一个集合S;用数组dis[]来记录v到S中各点的目前最短路径长度。然后不断地用贪心选择来扩充这个集合,并同时记录或修订数组dis[];直至S包含所有V中顶点。

(2.1)Dijkstra算法

​ ① 算法策略:由近到远逐步计算,每次找最近顶点距离作为最短路径长度,然后再从该最近者出发,即依据最近者修订到各顶点距离,再选出新的最近者,直到走完所有顶点。

​ ② 算法举例

QQ图片20231225171731

​ ③ Dijkstra算法的贪心选择性质:若u是V–S中具有最短路径的特殊顶点,就将u选入S,并确定了从源到u的最短路径长度D[u]。

​ ④ Dijkstra算法的时间复杂度:O(n2)。因为他有两层循环,外层循环n次,内层的两个循环一个是选出最小距离,一个是修订距离数组,他们次数都是n/2,所以时间复杂度为O(n2)。

3.2最小生成树问题

(1)Prim 算法

① 基本思想:在保证连通的前提下依次选出权重较小的n – 1条边(在实现中体现为n个顶点的选择)。

(下图中T为G的最小生成树)

QQ图片20231225163750

② 算法中的数据结构:

  • 用连接矩阵C[ i ] [ j ] 表示图,Cn [ i ] [ j ] 为结点 i 到 j 权重。
  • 对图中每个顶点设两个数组 closest [ j ] 和 lowcost [ j ] :closest [ j ] 是 s 中与 j 最近的顶点,即为选中的边; lowcost [ j ] 是相应边的权重。

③ 算法实现

Prim(int n, Type **c) {
    int j = 1; s[j] = true;
    for(int i = 2; i <= n; i++) {
        closest[i] = 1;
        lowcost[i] = c[1][i];
        s[i] = false;
    }
    for(int i = 1; i < n; i++) {
        min = inf;
        for(int k = 2; k <= n; k++) {
            if(lowcost[k] < min && !s[k]) {
                min = lowcost[k];
                j = k;
            }
         s[j] = true;
         for(int k = 2; k <= n; k++) {
             if(c[j][k] < lowcost[k] && !s[k]){
                 lowcost[k] = c[j][k];
                 closest[k] = j;
        }
    }
}

④ 算法示例

QQ图片20231225165524

(2)Kruskal算法

①基本思想:在保证无回路的前提下依次选择权重较小的n – 1条边。

QQ图片20231225165658

② 算法中的数据结构:

  • 数组 e [ ] [ ] 表示图的边。e [ i ] [ u ] ,e [ i ] [ v ] 表示边 i 的两个端点,e [ i ] [ w ] 表示边 i 的权重。
  • 使用 sort() 函数将数组按权重 w 从小到大排列。
  • 使用 initialize(n) 初始化;find(u) 找顶点所在集合;union(a,b) 合并集合a,b ;重载 != 判断集合是否相等。

③ 算法举例

QQ图片20231225170506

(3)对比 Prim算法 和 Kruskal算法

​ ① Prim算法为两重循环,外层循环n次,内层循环O(n),所以复杂性为O(n2) 。

​ ② Kruskal算法中,设边数为e,则边排序的时间为O(e),确定边的时间为O(loge),所以整个时间复杂性为O(eloge)。

​ ③ 点比边多时,用Kruskal算法更好,反之用Prim。

(4)用Kruskal算法得到的生成树T*必是最优树。

标签:总结,递归,int,复杂性,学习,算法,顶点,贪心
From: https://www.cnblogs.com/robber-is-best/p/17976785

相关文章

  • 人工智能学习总结_1
    人工智能一、人工智能绪论、基础(1)人工智能、基因工程、纳米科学被认为是21世纪的三大尖端技术。(2)人工智能的典型应用领域:交通、服务机器人、医疗健康、教育、公共安全、工作就业、娱乐。二、搜索(1)单智能体搜素:规划盲目搜索启发式搜索局部搜索(2)多智能体搜索:零和博弈极......
  • 人工智能学习总结_3
    人工智能七、神经网络7.1概述(1)适用问题:用于处理更加复杂的输入和输出之间的非线性关系问题(2)特点:​ ①可以用来拟合非常复杂的函数(3)应用:图像分类、语音识别、机器翻译、自动驾驶7.2人工神经网络设计(1)人工神经元:线性模型+激活函数(2)人工神经网络设计的三方面​ ①神经......
  • 人工智能学习总结_2
    人工智能四、线性回归4.1线性回归(1)线性回归特点:解释性强,简单,泛化能力稳定。(2)特征:输入的不同维度叫做特征。如果特征本身很重要,线性回归就很有效,但是挑选特征是非常困难的。(神经网络本质就是自动挑选、学习特征的机器)(3)最小化损失函数的方法:梯度下降法梯度下降法的计算4......
  • 学习笔记——KMP模式匹配
    KMP模式匹配KMP算法能够在线性时间内判定字符串\(A\left[1\simN\right]\)是否是字符串\(B\left[1\simM\right]\)的字串,并求出字符串\(A\)在字符串\(B\)中各次出现的位置。详细来讲,KMP算法分为两步。对字符串\(A\)进行自我匹配求出一个数组\(next\),\(next\lef......
  • Check for balanced parentheses using stack【1月20日学习笔记】
    点击查看代码//Checkforbalancedparenthesesusingstack#include<iostream>#include<stack>//stackfromstandardtemplatelibrary(STL)#include<string>usingnamespacestd;boolarepair(charopening,charclosing){ if(opening=='(&#......
  • 匈牙利算法
    描述若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的N(N为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2......
  • 关于SQL-case when最全面的学习笔记
    原文zhuanlan.zhihu.com/p/110198759?from_voters_page=truecasewhen推荐学习书籍:1、SQL基础教程6-32、SQL进阶教程1-1casewhen是SQL语法中提供的标准的条件分支。条件分支在MYSQL中即为IF函数,不同的数据库都会提供自己的一些函数,但是CASEWHEN更加通用。CASE语句......
  • 马拉车算法
    马拉车算法chars[maxn],ss[maxn];intp[maxn];intlen,center;intcnt=1;voidinit(){memset(s,0,sizeofs);cnt=1,s[0]='@';intlen=strlen(ss);for(inti=0;i<len;i++){s[cnt++]='#';s[cnt++]=ss......
  • 深度学习-神经网络原理-39
    目录1.神经网络算法是有监督的学习算法,2.分类3.训练4.代码进入新的内容,深度学习啦万事万物的产生不是一下子就变出来的,学术上也是,一点点的进步才催生出一门新的学科或者技术,神经网络用于机器学习也不例外,前面的机器学习的内容,线性回归,逻辑回归,多分类,决策树,以及各种集成学习......
  • 学习总结
    可以使用Vue作为前端框架,同时使用Python作为后端开发语言来实现你的想法。Vue是一个流行的JavaScript前端框架,它可以帮助你构建交互性强、响应式的用户界面。你可以使用Vue来创建页面布局、处理用户输入、进行数据绑定等等。而Python作为一种多用途的编程语言,也在后端开发领域非......