首页 > 编程语言 >「杂文」身为 ACMer 的我算法分析与设计居然挂了,我为什么会做这样的梦(雾)

「杂文」身为 ACMer 的我算法分析与设计居然挂了,我为什么会做这样的梦(雾)

时间:2024-06-11 20:44:20浏览次数:24  
标签:结点 杂文 ACMer 算法 最优 节点 限界 分支

目录

写在前面

臭打 ACM 的懂个屁的算法。

记录一些会考但是 ACM 中不会在意或者概念不一样的东西。

判断

  • 背包问题的最佳解决方案始终包含具有最大单位价值比vi/ci的对象i (错误)可能放不下。
  • 输入规模不是指输入数据的个数,而是数据在内存中所占空间的大小,也要考虑输入数据的长度。

简答

影响时间复杂度的因素

算法执行次数、数据规模、算法基本操作、输入数据特征(是否有序)

排序

  • 稳定排序算法:冒泡,插入,归并,计数,基数。
  • 不稳定排序算法:选择,快速,堆。

Prim 和 Kruskal 的异同

相同点:都是利用了最小生成树性质的贪心。

不同点:Prim:通过扩充连通节点子集来进行贪心选择;Kruskal 通过选择具有最小权的边的集合来进行贪心选择。

贪心和 DP 的区别

相同点:都是推导算法,都具有最优子结构性质。

不同点:

  • 贪心:

    • 每步决策仅由上一步的最优解推导下一步的最优解,上一步以前的最优解不做保留。
    • 每一步的最优解必定包含上一步的最优解。
    • 自顶向下的,当前的求解不依赖于有待于做出的选择和子问题(即子树的状况),仅需选择当前局部最优解。
    • 只有一个子问题。
  • 动态规划:

    • 全局最优解中必定包含某个局部最优解,但不必定包含前一个局部最优解,所以须要记录以前的全部最优解 (无后效性)
    • 关键是状态转移方程,即如何由已求出的局部最优解来推导全局最优解。
    • 自底向上的,通过子节点求出根节点,相对于贪心算法来说开销比较大。
    • 有多个子问题

优缺点:

DP:优点是可以得到全局最优解;缺点是空间开销大,需要计算所有子问题
贪心:优点是思维复杂度低、代码量小、时空复杂度低;缺点是有时只能得到局部最优解。

DP 与分治的区别

相同点:都是把原问题划分为多个子问题求解。

不同点:

动态规划:

  • 子问题并不是互相独立,同一个子问题可以同来求解多个问题。
  • 多数自底而上来求解问题,利用额外的空间存储子问题的结果。
  • 一般用于解决最优问题。

分治:

  • 分子问题相互独立的,一个子问题只能求解一个问题。
  • 分治一般自顶向下递归求解。
  • 解决通用问题。

贪心,DP 与分治

标准分治 动态规划 贪心算法
适用类型 通用问题 优化问题 优化问题
子问题结构 子问题不同 子问题重复(不独立) 只有一个子问题
最优子结构 不需要每个 必须满足 必须满足
子问题数 全部子问题 全部子问题 只要解决一个
子问题在最优解里 全部 部分 部分
选择与求解次序 先选择后解决子问题 先解决子问题后选择 先选择子问题后解决

分支界限法和回溯法的异同

  • 求解目标不同:回溯法的一般是找出解空间树中满足条件的所有解。分支限界法则是尽快找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。
  • 搜索方式不同:回溯法深度优先,遍历结点搜索解空间树;分支限界法广度优先或最小耗费优先搜索解空间树。
  • 存储空间不同:分支限界法加入了活结点表,存储空间比回溯法大得多。
  • 扩展结点的方式不同:分支限界法中每个活结点只有一次机会变成扩展结点,一旦成为扩展结点便一次性生成其所有子结点。

应用:回溯法空间效率更高,分支限界法由于只需求一个解因此一般效率更高。

方法 回溯法 分支限界法
对解空间树的搜索方式 深度优先搜索 广度优先或最小耗费优先搜索
存储结点的常用数据结构 搜索过程中动态产生问题的解空间 队列、优先队列
结点存储特性 活结点的所有可行子结点被遍历后才被从栈中弹出 每个结点只有一次成为活结点的机会
主要应用 找出满足约束条件的所有解 找出满足约束条件的一个解或特定意义下的最优解

计算与算法应用题

复杂度计算

见:「笔记」递归算法复杂度分析 - Luckyblock - 博客园

分支界限法

类似于回溯法,是一种在问题的解空间树T上搜索问题解的算法。但一般情况下与回溯法的求解目标不同。回溯法的求解目标是找出T中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。

分支限界法首先生成当前扩展结点的所有分支,然后再从所有活结点中选择一个作为扩展结点。每一个活结点都要计算限界,根据限界情况判断是否剪枝,或选择最有利的结点

分支限界法有两种不同的搜索空间树方式,分别为广度优先和最小耗费优先,它们对应两种不同的方法:

  • 队列式分支限界法(FIFO):常规的广度优先策略。按照先进先出的原则选取下一个扩展结点,以队列储存活结点。
  • 优先队列式分支限界法/最小耗费优先分支限界法(LC):按照优先队列中指定的优先级,选取优先级最高的结点作为下一个扩展结点,以优先队列储存。

上述两种方法分别与两种策略对应:

  • 按顺序选择结点作为下一次的扩展结点。优点是节省空间,缺点是需要计算的分支数较多,时间花费大;
  • 每次计算完限界后,找出限界最优的结点,作为下一次的扩展结点。优点是计算的分支数少,缺点是需要额外空间。

限界函数很大程度上决定了算法的效率。同一问题可以设计不同的限界函数。

  • FIFO 分支限界法中,常以约束条件作为限界函数,满足约束条件才可入队,不满足约束条件的舍弃。
  • LC 分支限界法中,还可以设计一个启发函数作为限界函数。

对于有约束的问题,FIFO法和LC法均可以求解;对于无约束问题,宜使用LC法。

实际上是一种基于剪枝的启发式搜索。

例题见下。

分支界限法背包

定义:\(W\) 表示当前所有选择物品的重量之和,\(P\) 表示当前所有选择物品的价值之和,\(BP\) 表示搜索到的所有可行解中的价值的最大值。

根节点代表扩展结点,其余每一层代表一个物品的选择情况,选中该物品则向左子树进行递归判断,否则向右子树递归。发现这是一棵二叉树,且从根节点到叶节点的 \(2^n\) 条路径与 \(2^n\) 种可能的选择方案一一对应。具体执行操作如下所示:

  1. 所有物品按单位价值降序排列。
  2. 从根节点(扩展节点)出发开始搜索;
  3. 对于第 \(i\) 层(代表物品 \((w_i, p_i)\))的节点,先尝试搜索左子树表示尝试选择该物品,判断是否满足约束条件(当前该物品是否可以装入背包?):
    • 若可以选择则令 \(W:=W + w_i, P:=P + p_i\),继续向下搜索;
    • 直至遇到不可行解时,开始向上回溯,取出最后一个装入的物品,进入右子树。
  4. 否则进入右子树,首先计算当前节点的上界 \(U\),若 \(U > BP\) 则剪去右子树继续向上回溯;否则回到步骤 3;
  5. 遇到叶子节点,比较当前价值与 \(BP\),若 \(P>BP\),则 \(BP:=P\)。
  6. 直到遍历完所有的节点(除剪枝部分外)。

一张我自己都懒得看的图:

image.png

分支界限法求单源最短路径

参考:算法分析与设计:分支限界法_分支界限法的效率与哪些因素有关-CSDN博客

求最短的路径,考虑使用优先队列式分支限界法,以减少计算的分支数。以下图为例:

20200416163914170.png
  1. 生成根节点的所有分支,全部入队列并记录路径;
  2. 在队列中选择路径最短的分支作为扩展结点
  3. 逐个生成分支,并判断分支的路径是否小于记录的最短路径;
    • 若不小于,舍弃该分支;
    • 若小于,该分支入队列;
  4. 生成所有分支后,回到2;
  5. 当队列为空时,算法结束。

分支界限搜索树:

image.png

树上所有根节点到其他节点的路径均代表一条搜索过程中访问到的路径,对于每个节点最后搜索到的从根节点到该节点的路径即为到达该节点的最短路径。

算法设计题

这个真是随便 AK。

写在最后

参考:

标签:结点,杂文,ACMer,算法,最优,节点,限界,分支
From: https://www.cnblogs.com/luckyblock/p/18242695

相关文章

  • 落实算法安全主体责任基本情况怎么写?(附模板)
    随着数字经济的高速发展,算法应用本身带来的社会问题不断积累,引起社会的广泛关注,于是在2021年12月31日,国家网信办会同工信部、公安部、市场监管总局出台《互联网信息服务算法推荐管理规定》,全面规范互联网信息服务算法活动,旨在实现算法技术创新与用户权益保障之间的动态平衡。《......
  • Canny边缘检测算法
    一、概念Canny算法是一种经典的图像处理算法,用于图像中的边缘检测,其实现的步骤包括:高斯滤波;计算梯度和方向:对平滑后的图像使用Sobel算子计算水平方向和竖直方向的一阶导数,然后计算该点的梯度大小和方向;非极大值抑制:对梯度图上的每个像素,根据其梯度方向,确定在该方向上的两个......
  • 基于分类算法的学习失败预警(机器学习课程期末设计报告)
    目录一.课设背景1.1设计要求1.2项目概述二.实验环境三.设计原理3.1理论知识3.1.1学习失败风险预测流程3.1.2数据预处理3.1.2.1缺失值处理(空值填充)3.1.2.2数据平衡3.1.2.3标准化处理3.1.3构建模型进行训练3.1.3.1网格搜索3.1.3.2随机森林算法3.1.2.3......
  • Java数据结构与算法(回溯算法)
    前言回溯算法是一种通过构建问题的解树(或解图)来逐步构建候选解的通用算法。它尝试通过一系列选择来解决问题,选择可能包括移动、添加一个元素到当前解、决定一个解的某部分等。当发现某个选择无法导致一个有效解时,算法会回退(即回溯),撤销该选择,并尝试其他选择。回溯算法通常用于......
  • 算法课程笔记——树状数组基础
    算法课程笔记——树状数组基础如果不这样写会一直循环出错......
  • 有趣的算法题之购物单
    购物单王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:主件附件电脑打印机,扫描仪书柜图书书桌台灯,文具工作椅无如果要买归类为附件的物品,必须先买该附件所属的主件,且每件物品只能购买一次。每个主件可以有 ......
  • Pytorch 实现简单的 线性回归 算法
    Pytorch实现简单的线性回归算法简单tensor的运算Pytorch涉及的基本数据类型是tensor(张量)和Autograd(自动微分变量)importtorchx=torch.rand(5,3)#产生一个5*3的tensor,在[0,1)之间随机取值y=torch.ones(5,3)#产生一个5*3的Tensor,元素都是1z=x+y......
  • 代码随想录算法训练营第9天 |
    28.strStr()https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/实现strStr()代码随想录https://programmercarl.com/0028.实现strStr.html#思路459.重复字符串https://leetcode.cn/problems/repeated-substring-pattern/submis......
  • Dijkstra 算法的手动分析
    目录Dijkstra算法step0.初始状态step1.第一轮step2.第二轮step3.第三轮step4.第四轮Dijkstra算法以下面有向图为例:graphLRV0((V0))--10-->V1((V1))V0((V0))--5-->V4((V4))V1((V1))--2-->V4((V4))V4((V4))--3-->V1((V1))V1((V1))--1-->V2((V2)......
  • RSA算法中,为什么需要的是两个素数?
    PrimiHub一款由密码学专家团队打造的开源隐私计算平台,专注于分享数据安全、密码学、联邦学习、同态加密等隐私计算领域的技术和内容。RSA算法中,为什么需要的是两个素数?RSA算法是一种广泛使用的非对称加密技术,基于大数分解的困难性。本文将探讨为什么RSA算法需要两个素数,并以通......