首页 > 编程语言 >【技术积累】算法中的动态规划【二】

【技术积累】算法中的动态规划【二】

时间:2023-06-09 16:22:04浏览次数:29  
标签:积累 状态 方程 问题 算法 计算 动态 规划

动态规划的优缺点是什么? 

动态规划的优点是:

  1. 可以解决一些复杂的问题,例如背包问题、最长公共子序列问题等;
  2. 可以通过记忆化搜索来避免重复计算,提高效率;
  3. 可以通过状态转移方程来简化问题,使问题更易于理解和解决;
  4. 可以处理连续的问题,例如最大子段和问题。

动态规划的缺点是:

  1. 对于某些问题,动态规划的时间和空间复杂度非常高,难以处理大规模的问题;
  2. 动态规划需要构建状态转移方程,需要一定的数学能力和思维能力;
  3. 动态规划无法处理一些特殊的问题,例如NP完全问题。

动态规划和递归的区别?

动态规划和递归的区别在于它们解决问题的方式。

递归是一种自上而下的解决问题的方法,它将问题分解成更小的子问题,并通过递归调用自身来解决这些子问题。

动态规划则是一种自下而上的解决问题的方法,它从最小的子问题开始解决,然后通过计算子问题的解来逐步解决更大的问题。

动态规划通常会使用一个表格来存储子问题的解,以避免重复计算。

因此,虽然递归和动态规划都可以解决相同的问题,但它们的解决方式不同,动态规划通常比递归更高效。

什么是最优子结构?为什么它对动态规划很重要?

最优子结构是指问题的最优解包含其子问题的最优解。

也就是说,如果我们能够通过求解子问题的最优解来得到原问题的最优解,那么这个问题就具有最优子结构性质。

最优子结构对于动态规划非常重要,因为它使得我们可以通过解决子问题来求解原问题,从而将原问题分解成更小的子问题。

这种分解问题的方式使得动态规划可以高效地解决大规模的问题。

同时,最优子结构还可以帮助我们设计状态转移方程,以便我们能够通过子问题的解来计算原问题的解。

因此,最优子结构是动态规划的一个重要概念,它使得我们能够高效地解决许多复杂的问题。

什么是重叠子问题?如何避免它们?

重叠子问题是指在解决一个问题的过程中,需要多次求解同一个子问题。这种重复计算会浪费计算资源,导致算法效率降低。

动态规划通过记忆化搜索来避免重叠子问题。

在动态规划中,我们通常会使用一个表格来存储子问题的解,以便在需要时可以直接查找,避免重复计算。

具体来说,当我们需要解决一个子问题时,我们首先检查表格中是否已经有了这个子问题的解,如果有,我们就直接返回表格中的解。

如果没有,我们就计算这个子问题的解,并将其存储到表格中。

这样,当我们需要解决同一个子问题时,就可以直接从表格中查找,避免重复计算,提高算法效率。

什么是记忆化搜索?它如何与动态规划相关?

记忆化搜索是一种优化搜索算法的方式,它通过记忆已经计算过的结果来避免重复计算。

在记忆化搜索中,我们通常会使用一个表格来存储已经计算过的结果,以便在需要时可以直接查找,避免重复计算。

记忆化搜索通常用于解决递归问题,例如斐波那契数列等。 

动态规划实际上就是一种记忆化搜索的方法,它通过使用一个表格来存储子问题的解,避免了重复计算。

动态规划通常用于解决具有最优子结构的问题,例如背包问题、最长公共子序列问题等。

因此,记忆化搜索和动态规划在本质上是相同的,都是通过记忆已经计算过的结果来避免重复计算,提高算法效率。

什么是状态转移方程?如何构建它们?

状态转移方程是动态规划中的一个重要概念,它描述了如何通过子问题的解来计算原问题的解。通常情况下,状态转移方程可以通过以下步骤来构建:

  1. 定义状态:首先需要定义状态,也就是问题的子问题的解。状态应该尽量简单,以便于计算。
  2. 定义状态转移方程:接下来需要定义状态转移方程,也就是描述如何通过子问题的解来计算原问题的解。状态转移方程应该尽量简单,以便于计算,并且应该具有最优子结构性质。
  3. 初始化状态:在动态规划中,通常需要初始化一些状态,以便于计算后续的状态。初始化状态应该尽量简单,以便于计算。
  4. 计算状态:最后需要计算状态,也就是根据状态转移方程计算出原问题的解。在计算状态时,应该遵循从小到大的顺序,以便于使用已经计算过的状态来计算后续的状态。

总之,状态转移方程是动态规划中的一个重要概念,它描述了如何通过子问题的解来计算原问题的解。构建状态转移方程的关键在于定义状态和状态转移方程,以及初始化状态和计算状态。

动态规划解决博弈论问题?

博弈论问题是指在多个参与者之间进行决策的情况下,如何制定最佳策略的问题。

在动态规划中,我们通常会使用一个表格来存储子问题的解,以便在需要时可以直接查找,避免重复计算。

下面我们以经典的石子游戏问题为例,说明如何用动态规划解决博弈论问题。

有一堆石子,两个玩家轮流取走石子,每次可以取走1个、2个或3个石子,取走最后一个石子的玩家获胜。假设两个玩家都采取最优策略,问先手玩家是否必胜?

  1. 定义状态:设f[i]表示还剩下i个石子时,先手玩家是否必胜。
  2. 定义状态转移方程:当还剩下i个石子时,先手玩家可以取走1个、2个或3个石子,然后变成后手玩家,后手玩家也可以取走1个、2个或3个石子,然后变成先手玩家。
  3. 因此,当先手玩家取走k个石子时,状态方程为f[i] = !f[i-k](1<=k<=3)。
  4. 也就是说,当先手玩家取走k个石子时,如果后手玩家在剩下的i-k个石子中必败,则先手玩家必胜,否则先手玩家必败。
  5. 初始化状态:f[0] = false,表示没有石子时先手玩家必败。
  6. 计算状态:根据状态转移方程,从小到大计算f[i]的值,最终得到f[n]的值,表示还剩下n个石子时,先手玩家是否必胜。
stone_game(n):
    f = [False] * (n+1)
    f[0] = False
    for i in range(1, n+1):
        for k in range(1, 4):
            if i >= k and not f[i-k]:
                f[i] = True
                break
    return f[n]

以上就是用动态规划解决博弈论问题的一个例子,通过定义状态、状态转移方程、初始化状态和计算状态,我们可以解决多种博弈论问题。

动态规划解决最大二分配问题?

最大二分匹配问题是指在一个二分图中,找到最大的匹配数,即在图中找到最多的不相交的边数。

下面以一个简单的例子来说明如何用动态规划解决最大二分匹配问题。

有一个二分图,其中左侧有n个节点,右侧有m个节点,二分图中存在一些边连接左侧和右侧的节点,找出最大的匹配数。

  1. 定义状态:设f[i][j]表示左侧的前i个节点和右侧的前j个节点之间的最大匹配数。
  2. 定义状态转移方程:当考虑节点i和节点j之间的匹配时,有两种情况:
    • 节点i和节点j不匹配,此时f[i][j] = f[i][j-1],即只考虑左侧的前i个节点和右侧的前j-1个节点之间的最大匹配数。
    • 节点i和节点j匹配,此时f[i][j] = f[i-1][j-1] + 1,即左侧的前i-1个节点和右侧的前j-1个节点之间的最大匹配数再加上节点i和节点j之间的一条边。
  3. 初始化状态:f[0][0] = 0,表示左侧和右侧都没有节点时,匹配数为0。
  4. 计算状态:根据状态转移方程,从小到大计算f[i][j]的值,最终得到f[n][m]的值,表示左侧的前n个节点和右侧的前m个节点之间的最大匹配数。
max_bipartite_matching(n, m, edges):
    f = [[0] * (m+1) for _ in range(n+1)]
    for i in range(1, n+1):
        for j in range(1, m+1):
            if (i-1, j-1) in edges:
                f[i][j] = f[i-1][j-1] + 1
            else:
                f[i][j] = max(f[i][j-1], f[i-1][j])
    return f[n][m]


以上就是用动态规划解决最大二分匹配问题的一个例子,通过定义状态、状态转移方程、初始化状态和计算状态,我们可以解决多种最大二分匹配问题。

动态规划解决字符串匹配问题?

字符串匹配问题是指在一个字符串中查找另一个字符串的位置。

下面以一个简单的例子来说明如何用动态规划解决字符串匹配问题。

给定两个字符串s和t,判断s中是否包含t。

  1. 定义状态:设f[i][j]表示字符串s的前i个字符和字符串t的前j个字符是否匹配。
  2. 定义状态转移方程:当考虑字符s[i]和字符t[j]时,有两种情况:
    • 字符s[i]和字符t[j]不匹配,此时f[i][j] = False。
    • 字符s[i]和字符t[j]匹配,此时f[i][j] = f[i-1][j-1],即字符串s的前i-1个字符和字符串t的前j-1个字符是否匹配。
  3. 初始化状态:f[0][0] = True,表示两个空字符串是匹配的。
  4. 计算状态:根据状态转移方程,从小到大计算f[i][j]的值,最终得到f[m][n]的值,表示字符串s中是否包含字符串t。
string_matching(s, t):
    m, n = len(s), len(t)
    f = [[False] * (n+1) for _ in range(m+1)]
    f[0][0] = True
    for i in range(1, m+1):
        for j in range(1, n+1):
            if s[i-1] == t[j-1]:
                f[i][j] = f[i-1][j-1]
            else:
                f[i][j] = False
    return f[m][n]


以上就是用动态规划解决字符串匹配问题的一个例子,通过定义状态、状态转移方程、初始化状态和计算状态,我们可以解决多种字符串匹配问题。

动态规划解决序列模式匹配问题?

最大独立集问题是指在一个无向图中,找到一个最大的独立顶点集合,使得这些顶点之间没有边相连。动态规划是解决最大独立集问题的一种常用方法。下面

给定一个无向图G=(V,E),求出最大的独立顶点集合。

  1. 定义状态:设f[i]表示以顶点i为结尾的最大独立集大小。
  2. 定义状态转移方程:当考虑顶点i时,有两种情况:
    • 顶点i不在最大独立集中,此时f[i] = f[i-1]
    • 顶点i在最大独立集中,此时f[i] = f[i-2] + w[i],其中w[i]表示顶点i的权值。
  3. 因为如果顶点i在最大独立集中,那么顶点i-1一定不在最大独立集中,所以f[i] = f[i-2] + w[i]。
  4. 初始化状态:f[0] = 0,f[1] = w[1]。
  5. 计算状态:根据状态转移方程,从小到大计算f[i]的值,最终得到最大的独立集大小为max(f[i])。
max_independent_set(w):
    n = len(w)
    f = [0] * (n+1)
    f[1] = w[0]
    for i in range(2, n+1):
        f[i] = max(f[i-1], f[i-2] + w[i-1])
    return f[n]

以上就是用动态规划解决最大独立集问题的一个例子,通过定义状态、状态转移方程、初始化状态和计算状态,我们可以解决多种最大独立集问题。

标签:积累,状态,方程,问题,算法,计算,动态,规划
From: https://www.cnblogs.com/yyyyfly1/p/17469529.html

相关文章

  • 密码学(4):常见对称算法
    叨两句密码系列文章,是对接第三方接口时接触到加解密,但是知识体系较乱。希望能整理常见证书、密钥、加解密方式这方面知识,用于简单理解和快速区分。有些缺漏和待补充,后续慢慢完善。有任何问题欢迎提出,便于及时修正前言块加密(分组加密):加密算法无法一次性处理过长的明文,这种情况......
  • 密码学(5):常见非对称加密算法
    叨两句密码系列文章,是对接第三方接口时接触到加解密,但是知识体系较乱。希望能整理常见证书、密钥、加解密方式这方面知识,用于简单理解和快速区分。有些缺漏和待补充,后续慢慢完善。有任何问题欢迎提出,便于及时修正1.RSA算法1.介绍2.依赖的数学原理1)将两个大素数相乘十分容......
  • 路由算法
    一、RIP算法——内部网关协议1.路由选择:基于距离向量,所以选择的是路由数最少得路径,而不一定是代价最小的路径2.适用于小型互联网,允许一条路径最多只能包含15个路由器,当距离等于16时,表示不可达。3.交换信息的特点:仅和相邻路由器交换信息,交换全部路由,按固定的时间间隔交换路由4.......
  • 算法基础(一):串匹配问题(BF,KMP算法)
    好家伙,学算法,这篇看完,如果没有学会KMP算法,麻烦给我点踩希望你能拿起纸和笔,一边阅读一边思考,看完这篇文章大概需要(20分钟的时间) 我们学这个算法是为了解决串匹配的问题那什么是串匹配?举个例子:我要在"彭于晏吴彦祖"这段字符串中找到"吴彦祖"字符串这就是串匹配......
  • K-means(K均值聚类算法)算法笔记
    K-means(K均值聚类算法)算法笔记K-means算法,是比较简单的无监督的算法,通过设定好初始的类别k,然后不断循环迭代,将给定的数据自动分为K个类别。事实上,大家都知道K-means是怎么算的,但实际上,它是GMM(高斯混合模型)的一个特例,其而GMM是基于EM算法得来的,所以本文,将对K-means算法的算法思想......
  • EM算法笔记
    EM算法笔记背景    EM(Expectation-Maximum)算法也称期望最大化算法,是最常见的隐变量估计方法,它的思想在很多算法上有所体现。例如高斯混合模型(Gaussianmixturemodel,简称GMM)的参数;隐式马尔科夫算法(HMM)、LDA主题模型的变分推断、还有VAE、GAN等等。    在机器学习算......
  • RALB负载均衡算法的应用 | 京东云技术团队
    一、背景搜索推荐算法架构为京东集团所有的搜索推荐业务提供服务,实时返回处理结果给上游。部门各子系统已经实现了基于CPU的自适应限流,但是Client端对Server端的调用依然是RR轮询的方式,没有考虑下游机器性能差异的情况,无法最大化利用集群整体CPU,存在着Server端CPU不均衡的问题。京......
  • 密码学(1):常见算法分类
    前言有任何问题欢迎提出,便于及时修正......
  • python tkinter 动态批量建立Widget时,combobox 或 entry传递参数问题
    terminal_combobox.bind('<<ComboboxSelected>>',lambdaevent,arg=key_dict:self.terminal_select(key_dict=arg))#注意,传递参数方法defterminal_select(self,key_dict,*args):var=self.dict_widget[key_d......
  • 0011.有监督学习之Apriori算法
    一、关联分析概述1.关联分析2.频繁项集的评估标准2.1支持度2.2置信度2.3提升度3.关联规则发现二、Apriori算法原理三、使用Apriori算法来发现频繁项集1.生成候选项集2.项集迭代函数四、Apriori关联规则挖掘1.挖掘关联规则的流程2.关联规则的python实现五......