Python之动态规划算法
动态规划算法:
是一种解决棘手问题的方法,它将问题分成小问题,并先着手解决这些小问题。但仅当每个子问题都是离散的,即不依赖于其他子问题时,动态规划才管用。
在问题可分解为彼此独立且离散的子问题时,就可使用动态规划来解决。
设计动态规划解决方案的通用小贴士:
1、每个动态规划算法都从一个网格开始。
2、单元格中的值通常就是要优化的值。
3、每个单元格都是一个子问题,因此应考虑如何将问题分成子问题,这有助于找出网格的坐标轴。
最长公共子串:
两个字符串都包含的最长连续子串。
最长公共子序列:
两个字符串都包含的最长有序子串。
最长公共子串要求在原字符串中是连续的,而最长公共子序列只需要保持相对顺序一致,并不要求连续。
以下2例中待处理字符串:
# str_a = 'cnbalodgs'
# str_b = 'cbaelodng'# str_a = 'abcdfg'
# str_b = 'abdfg'str_a = 'abcbdab'
str_b = 'bdcaba'# str_a = 'abcbdecb'
# str_b = 'ebdeaba'
示例:获取最长公共子串
解法就是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若匹配则为1,否则为0。然后求出对角线最长的1的序列,其对应的位置就是最长匹配子串的位置。
# 此例中有多个相同长度的公共子串,但只能获取第一个子串
def find_lcsubstr(s1, s2): # 下面4行不要直接写在循环中,减少计算s1_len = len(s1) + 1 #为方便后续计算,多了1行1列 s2_len = len(s2) + 1s3_len = len(s1)s4_len = len(s2)m = [[0 for j in range(s2_len)] for i in range(s1_len)] #生成0矩阵maxNum = 0 #初始最长匹配长度p = 0 #匹配的起始位置for i in range(s3_len):for j in range(s4_len):if s1[i] == s2[j]: #相同则累加m[i + 1][j + 1] = m[i][j] + 1 #给相同字符赋值,值为左上角值加1if m[i + 1][j + 1] > maxNum:maxNum = m[i + 1][j + 1] #获取最大匹配长度p = i + 1 #记录最大匹配长度的终止位置print(m)return s1[p - maxNum : p], maxNum #返回最长子串及其长度
print(find_lcsubstr(str_a, str_b))
结果为:
[[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1], [0, 1, 0, 0, 0, 2, 0], [0, 0, 0, 1, 0, 0, 0], [0, 1, 0, 0, 0, 1, 0], [0, 0, 2, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1], [0, 1, 0, 0, 0, 2, 0]]
('ab', 2)
示例:获取最长公共子序列,可辨别显示多组相同长度的不同最长公共子序列(此为转载)
class LCS():# 读入待匹配的两个字符串def input(self, x, y): if type(x) != str or type(y) != str:print('input error')return Noneself.x = xself.y = y# 生成最长公共子序列矩阵def Compute_LCS(self):xlength = len(self.x)ylength = len(self.y)self.direction_list = [None] * xlength #这个二维列表存着回溯方向for i in range(xlength):self.direction_list[i] = [None] * ylengthself.lcslength_list = [None] * (xlength + 1) #这个二维列表存着当前最长公共子序列长度for j in range(xlength + 1):self.lcslength_list[j] = [None] * (ylength + 1)for i in range(0, xlength + 1): #二维列表第一列设置为0self.lcslength_list[i][0] = 0for j in range(0, ylength + 1): #二维列表第一行设置为0self.lcslength_list[0][j] = 0#下面是进行回溯方向和长度表的赋值for i in range(1, xlength + 1):for j in range(1, ylength + 1):if self.x[i - 1] == self.y[j - 1]:self.lcslength_list[i][j] = self.lcslength_list[i - 1][j - 1] + 1self.direction_list[i - 1][j - 1] = 0 #左上elif self.lcslength_list[i - 1][j] > self.lcslength_list[i][j - 1]:self.lcslength_list[i][j] = self.lcslength_list[i - 1][j]self.direction_list[i - 1][j - 1] = 1 #上elif self.lcslength_list[i - 1][j] < self.lcslength_list[i][j - 1]:self.lcslength_list[i][j] = self.lcslength_list[i][j - 1]self.direction_list[i - 1][j - 1] = -1 #左else:self.lcslength_list[i][j] = self.lcslength_list[i - 1][j]self.direction_list[i - 1][j - 1] = 2 #左或上self.lcslength = self.lcslength_list[-1][-1]# print(self.direction_list)# print(self.lcslength_list)return self.direction_list, self.lcslength_list# 生成最长公共子序列def printLCS(self, curlen, i, j, s):if i == 0 or j == 0:return Noneif self.direction_list[i - 1][j - 1] == 0:if curlen == self.lcslength:s += self.x[i - 1]for i in range(len(s)-1, -1, -1):print(s[i])print('\n')elif curlen < self.lcslength:s += self.x[i - 1]self.printLCS(curlen + 1, i - 1, j - 1, s)elif self.direction_list[i - 1][j - 1] == 1:self.printLCS(curlen, i - 1, j, s)elif self.direction_list[i - 1][j - 1] == -1:self.printLCS(curlen, i, j - 1, s)else:self.printLCS(curlen, i - 1, j, s)self.printLCS(curlen, i, j - 1, s)def returnLCS(self): #回溯的入口self.printLCS(1, len(self.x), len(self.y), '')if __name__ == '__main__':p = LCS() #实例化类p.input(str_a, str_b) #读入待匹配的两个字符串p.Compute_LCS() #生成最长公共子序列矩阵p.returnLCS() #生成最长公共子序列
结果为:
b
c
b
ab
c
a
bb
d
a
b
Python之动态规划算法相关推荐
- 详解动态规划算法(Python实现动态规划算法典型例题)
动态规划(Dynamic programming) 是一种在数学.计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法. 动态规划算法是通过拆分问题,定义问题状态和状 ...
- 八十五、Python | Leetcode数据结构之图和动态规划算法系列
@Author:Runsen @Date:2020/7/7 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...
- Python使用组合、排列和动态规划算法求解0-1背包问题
问题描述: 现有若干重量和价值各不相同的物品以及1个固定容量的背包,可以任意选择多个物品放入背包,如何让背包里装入的物品总价值最大?假设物品从0开始编号,输出在不超过背包容量的前提下放入背包能够使得物 ...
- python数据结构和算法 时间复杂度分析 乱序单词检测 线性数据结构 栈stack 字符匹配 表达式求值 queue队列 链表 递归 动态规划 排序和搜索 树 图
python数据结构和算法 参考 本文github 计算机科学是解决问题的研究.计算机科学使用抽象作为表示过程和数据的工具.抽象的数据类型允许程序员通过隐藏数据的细节来管理问题领域的复杂性.Pytho ...
- tsp问题动态规划python_用Python解决TSP问题(2)——动态规划算法
本介绍用python解决TSP问题的第二个方法--动态规划法 算法介绍 动态规划算法根据的原理是,可以将原问题细分为规模更小的子问题,并且原问题的最优解中包含了子问题的最优解.也就是说,动态规划是一种 ...
- Python算法分析与设计实验:动态规划算法
Python算法分析与设计实验:动态规划算法 一.实验目的 1.理解动态规划求解优化问题的典型步骤,以及动态规划算法求解计算问题的时间复杂度分析 2.熟练掌握利用动态规划算法求解一维.二维等典型优化问 ...
- Python数据结构与算法-动态规划(钢条切割问题)
一.动态规划(DP)介绍 1.从斐波那契数列看动态规划 (1)问题 斐波那契数列递推式: 练习:使用递归和非递归的方法来求解斐波那契数列的第n项 (2)递归方法的代码实现 import time # ...
- 【机器学习基础】数学推导+纯Python实现机器学习算法28:CRF条件随机场
Python机器学习算法实现 Author:louwill Machine Learning Lab 本文我们来看一下条件随机场(Conditional Random Field,CRF)模型.作为概 ...
- 化工热力学补考成功,几天没有头脑了,赶紧赏自己几题Leetcode动态规划算法最长系列
@Author:Runsen @Date:2020/10/9 "恭喜你昨天,化工热力学补考成功!" "区区化工热力学还想让我重修,只不过浪费了我九月一半的精力和十月的九成 ...
最新文章
- Design Pattern - Singleton(C#)
- 算法分析 载货问题_协会发布 | 汽车市场走势分析及2021年预测报告
- Java的Kafka:构建安全,可扩展的消息传递应用程序
- 实用常识_实用垃圾收集,第1部分–简介
- 前端小知识点(4):JS 运行机制和存储
- std::string中的反向迭代器rbegin()和rend()
- C++基础与深度解析第七章:深入IO
- Confluence 6 创建一个用户宏
- 写于公元2006年2月14日
- Qt编写地图综合应用30-世界地图
- vue JsBarcode的使用
- 计算机网络专业以后装网线,安装了1000M宽带后,您就不必再上网了吗?千兆宽带有多快?...
- iOS 屏幕适配 X XR XS XSMax 尺寸
- c 语言if函数嵌套使用方法,if函数的嵌套怎么用?
- 乘大潮而崛起,浪潮云洲大有可为
- wordpress插件Imagepaste的命名规则修改(一款 直接复制粘贴图片自动上传的编辑器增强插件)
- matlab编程勒让德多项式展开例题解析,第19 勒让德多项式 球函数习题及解答
- 卡片游戏--循环队列实现
- 补货中估计提前期不确定的需求分布公式推导
- win2003上不能与iphone同步问题解决
热门文章
- 类 workbook 的 saveas 方法无效_2021初级会计《经济法基础》知识点:一般计税方法应纳税额的计算...
- (一)STM32连上阿里云(附开源代码)
- CNN基础知识 || softmax与交叉熵
- 捕获PC微信支付消息的基本原理
- js技巧 console.log使用
- 日常生活开支记账明细_学会记账对个人理财的好处
- 怎么编辑发布百度词条
- 无线传输技术基础二 复用 扩频技术
- 【原创】一个计算斗地主谁必赢谁必输的程序
- 华为提出PyramidTNT:用金字塔结构改进Transformer!涨点明显!