Python算法:动态规划

2023-11-05

转载自伯乐在线

 

 

本节主要结合一些经典的动规问题介绍动态规划的备忘录法和迭代法这两种实现方式,并对这两种方式进行对比

大家都知道,动态规划算法一般都有下面两种实现方式,前者我称为递归版本,后者称为迭代版本,根据前面的知识可知,这两个版本是可以相互转换的

1.直接自顶向下实现递归式,并将中间结果保存,这叫备忘录法;

2.按照递归式自底向上地迭代,将结果保存在某个数据结构中求解。

编程有一个原则DRY=Don’t Repeat Yourself,就是说你的代码不要重复来重复去的,这个原则同样可以用于理解动态规划,动态规划除了满足最优子结构,它还存在子问题重叠的性质,我们不能重复地去解决这些子问题,所以我们将子问题的解保存起来,类似缓存机制,之后遇到这个子问题时直接取出子问题的解。

举个简单的例子,斐波那契数列中的元素的计算,很简单,我们写下如下的代码:

Python

1

2

3

def fib(i):

    if i<2: return 1

    return fib(i-1)+fib(i-2)

 

好,来测试下,运行fib(10)得到结果69,不错,速度也还行,换个大的数字,试试100,这时你会发现,这个程序执行不出结果了,为什么?递归太深了!要计算的子问题太多了!

所以,我们需要改进下,我们保存每次计算出来的子问题的解,用什么保存呢?用Python中的dict!那怎么实现保存子问题的解呢?用Python中的装饰器!

如果不是很了解Python的装饰器,可以快速看下这篇总结中关于装饰器的解释:Python Basics

修改刚才的程序,得到如下代码,定义一个函数memo返回我们需要的装饰器,这里用cache保存子问题的解,key是方法的参数,也就是数字n,值就是fib(n)返回的解。

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

from functools import wraps

 

def memo(func):

    cache={}

    @wraps(func)

    def wrap(*args):

        if args not in cache:

            cache[args]=func(*args)

        return cache[args]

    return wrap

 

@memo

def fib(i):

    if i<2: return 1

    return fib(i-1)+fib(i-2)

 

重新运行下fib(100),你会发现这次很快就得到了结果573147844013817084101,这就是动态规划的威力,上面使用的是第一种带备忘录的递归实现方式。

带备忘录的递归方式的优点就是易于理解,易于实现,代码简洁干净,运行速度也不错,直接从需要求解的问题出发,而且只计算需要求解的子问题,没有多余的计算。但是,它也有自己的缺点,因为是递归形式,所以有限的栈深度是它的硬伤,有些问题难免会出现栈溢出了。

于是,迭代版本的实现方式就诞生了!

迭代实现方式有2个好处:1.运行速度快,因为没有用栈去实现,也避免了栈溢出的情况;2.迭代实现的话可以不使用dict来进行缓存,而是使用其他的特殊cache结构,例如多维数组等更为高效的数据结构。

那怎么把递归版本转变成迭代版本呢?

这就是递归实现和迭代实现的重要区别:递归实现不需要去考虑计算顺序,只要给出问题,然后自顶向下去解就行;而迭代实现需要考虑计算顺序,并且顺序很重要,算法在运行的过程中要保证当前要计算的问题中的子问题的解已经是求解好了的。

斐波那契数列的迭代版本很简单,就是按顺序来计算就行了,不解释,关键是你可以看到我们就用了3个简单变量就求解出来了,没有使用任何高级的数据结构,节省了大量的空间。

Python

1

2

3

4

5

6

7

8

9

def fib_iter(n):

    if n<2: return 1

    a,b=1,1

    while n>=2:

        c=a+b

        a=b

        b=c

        n=n-1

    return c

 

斐波那契数列的变种经常出现在上楼梯的走法问题中,每次只能走一个台阶或者两个台阶,广义上思考的话,动态规划也就是一个连续决策问题,到底当前这一步是选择它(走一步)还是不选择它(走两步)呢?

其他问题也可以很快地变相思考发现它们其实是一样的,例如求二项式系数C(n,k),杨辉三角(求从源点到目标点有多少种走法)等等问题。

二项式系数C(n,k)表示从n个中选k个,假设我们现在处理n个中的第1个,考虑是否选择它。如果选择它的话,那么我们还需要从剩下的n-1个中选k-1个,即C(n-1,k-1);如果不选择它的话,我们需要从剩下的n-1中选k个,即C(n-1,k)。所以,C(n,k)=C(n-1,k-1)+C(n-1,k)

结合前面的装饰器,我们很快便可以实现求二项式系数的递归实现代码,其中的memo函数完全没变,只是在函数cnk前面添加了@memo而已,就这么简单!

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

from functools import wraps

 

def memo(func):

    cache={}

    @wraps(func)

    def wrap(*args):

        if args not in cache:

            cache[args]=func(*args)

        return cache[args]

    return wrap

 

@memo

def cnk(n,k):

    if k==0: return 1 #the order of `if` should not change!!!

    if n==0: return 0

    return cnk(n-1,k)+cnk(n-1,k-1)

 

它的迭代版本也比较简单,这里使用了defaultdict,略高级的数据结构,和dict不同的是,当查找的key不存在对应的value时,会返回一个默认的值,这个很有用,下面的代码可以看到。 如果不了解defaultdict的话可以看下Python中的高级数据结构

Python

1

2

3

4

5

6

7

8

9

10

from collections import defaultdict

 

n,k=10,7

C=defaultdict(int)

for row in range(n+1):

    C[row,0]=1

    for col in range(1,k+1):

        C[row,col]=C[row-1,col-1]+C[row-1,col]

 

print(C[n,k]) #120

 

杨辉三角大家都熟悉,在国外这个叫Pascal Triangle,它和二项式系数特别相似,看下图,除了两边的数字之外,里面的任何一个数字都是由它上面相邻的两个元素相加得到,想想C(n,k)=C(n-1,k-1)+C(n-1,k)不也就是这个含义吗?

所以说,顺序对于迭代版本的动态规划实现很重要,下面举个实例,用动态规划解决有向无环图的单源最短路径问题。假设有如下图所示的图,当然,我们看到的是这个有向无环图经过了拓扑排序之后的结果,从a到f的最短路径用灰色标明了。

好,怎么实现呢?

我们有两种思考方式:

1.”去哪里?”:我们顺向思维,首先假设从a点出发到所有其他点的距离都是无穷大,然后,按照拓扑排序的顺序,从a点出发,接着更新a点能够到达的其他的点的距离,那么就是b点和f点,b点的距离变成2,f点的距离变成9。因为这个有向无环图是经过了拓扑排序的,所以按照拓扑顺序访问一遍所有的点(到了目标点就可以停止了)就能够得到a点到所有已访问到的点的最短距离,也就是说,当到达哪个点的时候,我们就找到了从a点到该点的最短距离,拓扑排序保证了后面的点不会指向前面的点,所以访问到后面的点时不可能再更新它前面的点的最短距离!(这里的更新也就是前面第4节介绍过的relaxtion)这种思维方式的代码实现就是迭代版本。

[这里涉及到了拓扑排序,前面第5节Traversal中介绍过了,这里为了方便没看前面的童鞋理解,W直接使用的是经过拓扑排序之后的结果。]

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

def topsort(W):

    return W

 

def dag_sp(W, s, t):

    d = {u:float('inf') for u in W} #

    d[s] = 0

    for u in topsort(W):

        if u == t: break

        for v in W[u]:

            d[v] = min(d[v], d[u] + W[u][v])

    return d[t]

 

#邻接表

W={0:{1:2,5:9},1:{2:1,3:2,5:6},2:{3:7},3:{4:2,5:3},4:{5:4},5:{}}

s,t=0,5

print(dag_sp(W,s,t)) #7

 

用图来表示计算过程就是下面所示:

2.”从哪里来?”:我们逆向思维,目标是要到f,那从a点经过哪个点到f点会近些呢?只能是求解从a点出发能够到达的那些点哪个距离f点更近,这里a点能够到达b点和f点,f点到f点距离是0,但是a到f点的距离是9,可能不是最近的路,所以还要看b点到f点有多近,看b点到f点有多近就是求解从b点出发能够到达的那些点哪个距离f点更近,所以又绕回来了,也就是递归下去,直到我们能够回答从a点经过哪个点到f点会更近。这种思维方式的代码实现就是递归版本。

这种情况下,不需要输入是经过了拓扑排序的,所以你可以任意修改输入W中节点的顺序,结果都是一样的,而上面采用迭代实现方式必须要是拓扑排序了的,从中你就可以看出迭代版本和递归版本的区别了。

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

from functools import wraps

def memo(func):

    cache={}

    @wraps(func)

    def wrap(*args):

        if args not in cache:

            cache[args]=func(*args)

            # print('cache {0} = {1}'.format(args[0],cache[args]))

        return cache[args]

    return wrap

 

def rec_dag_sp(W, s, t):

    @memo

    def d(u):

        if u == t: return 0

        return min(W[u][v]+d(v) for v in W[u])

    return d(s)

 

#邻接表

W={0:{1:2,5:9},1:{2:1,3:2,5:6},2:{3:7},3:{4:2,5:3},4:{5:4},5:{}}

s,t=0,5

print(rec_dag_sp(W,s,t)) #7

 

用图来表示计算过程就如下图所示:

[扩展内容:对DAG求单源最短路径的动态规划问题的总结,比较难理解,附上原文]

Although the basic algorithm is the same, there are many ways of finding the shortest path in a DAG, and, by extension, solving most DP problems. You could do it recursively, with memoization, or you could do it iteratively, with relaxation. For the recursion, you could start at the first node, try various “next steps,” and then recurse on the remainder, or (if you graph representation permits) you could look at the last node and try “previous steps” and recurse on the initial part. The former is usually much more natural, while the latter corresponds more closely to what happens in the iterative version.

Now, if you use the iterative version, you also have two choices: you can relax the edges out of each node (in topologically sorted order), or you can relax all edges into each node. The latter more obviously yields a correct result but requires access to nodes by following edges backward. This isn’t as far-fetched as it seems when you’re working with an implicit DAG in some nongraph problem. (For example, in the longest increasing subsequence problem, discussed later in this chapter, looking at all backward “edges” can be a useful perspective.)

Outward relaxation, called reaching, is exactly equivalent when you relax all edges. As explained, once you get to a node, all its in-edges will have been relaxed anyway. However, with reaching, you can do something that’s hard in the recursive version (or relaxing in-edges): pruning. If, for example, you’re only interested in finding all nodes that are within a distance r, you can skip any node that has distance estimate greater than r. You will still need to visit every node, but you can potentially ignore lots of edges during the relaxation. This won’t affect the asymptotic running time, though (Exercise 8-6).

Note that finding the shortest paths in a DAG is surprisingly similar to, for example, finding the longest path, or even counting the number of paths between two nodes in a DAG. The latter problem is exactly what we did with Pascal’s triangle earlier; the exact same approach would work for an arbitrary graph. These things aren’t quite as easy for general graphs, though. Finding shortest paths in a general graph is a bit harder (in fact, Chapter 9 is devoted to this topic), while finding the longest path is an unsolved problem (see Chapter 11 for more on this).

好,我们差不多搞清楚了动态规划的本质以及两种实现方式的优缺点,下面我们来实践下,举最常用的例子:矩阵链乘问题,内容较多,所以请点击链接过去阅读完了之后回来看总结

OK,希望我把动态规划讲清楚了,总结下:动态规划其实就是一个连续决策的过程,每次决策我们可能有多种选择(二项式系数和0-1背包问题中我们只有两个选择,DAG图的单源最短路径中我们的选择要看点的出边或者入边,矩阵链乘问题中就是矩阵链可以分开的位置总数…),我们每次选择最好的那个作为我们的决策。所以,动态规划的时间复杂度其实和这两者有关,也就是子问题的个数以及子问题的选择个数,一般情况下动态规划算法的时间复杂度就是两者的乘积。

动态规划有两种实现方式:一种是带备忘录的递归形式,这种方式直接从原问题出发,遇到子问题就去求解子问题并存储子问题的解,下次遇到的时候直接取出来,问题求解的过程看起来就像是先自顶向下地展开问题,然后自下而上的进行决策;另一个实现方式是迭代方式,这种方式需要考虑如何给定一个子问题的求解方式,使得后面求解规模较大的问题是需要求解的子问题都已经求解好了,它的缺点就是可能有些子问题不要算但是它还是算了,而递归实现方式只会计算它需要求解的子问题。


练习1:来试试写写最长公共子序列吧,这篇文章中给出了Python版本的5种实现方式哟!

练习2:算法导论问题 15-4: Planning a company party 计划一个公司聚会

Start example Professor Stewart is consulting for the president of a corporation that is planning a company party. The company has a hierarchical structure; that is, the supervisor relation forms a tree rooted at the president. The personnel office has ranked each employee with a conviviality rating, which is a real number. In order to make the party fun for all attendees, the president does not want both an employee and his or her immediate supervisor to attend.

Professor Stewart is given the tree that describes the structure of the corporation, using the left-child, right-sibling representation described in Section 10.4. Each node of the tree holds, in addition to the pointers, the name of an employee and that employee’s conviviality ranking. Describe an algorithm to make up a guest list that maximizes the sum of the conviviality ratings of the guests. Analyze the running time of your algorithm.

原问题可以转换成:假设有一棵树,用左孩子右兄弟的表示方式表示,树的每个结点有个值,选了某个结点,就不能选择它的父结点,求整棵树选的节点值最大是多少。

假设如下:

dp[i][0]表示不选i结点时,i子树的最大价值

dp[i][1]表示选i结点时,i子树的最大价值

列出状态方程

dp[i][0] = sum(max(dp[u][0], dp[u][1]))  (如果不选i结点,u为结点i的儿子)

dp[i][1] = sum(dp[u][0]) + val[i]  (如果选i结点,val[i]表示i结点的价值)

最后就是求max(dp[root][0], dp[root][1])

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python算法:动态规划 的相关文章

  • Python 的键盘中断不会中止 Rust 函数 (PyO3)

    我有一个使用 PyO3 用 Rust 编写的 Python 库 它涉及一些昂贵的计算 单个函数调用最多需要 10 分钟 从 Python 调用时如何中止执行 Ctrl C 好像只有执行结束后才会处理 所以本质上没什么用 最小可重现示例 Ca
  • 将 Matplotlib 误差线放置在不位于条形中心的位置

    我正在 Matplotlib 中生成带有错误栏的堆积条形图 不幸的是 某些层相对较小且数据多样 因此多个层的错误条可能重叠 从而使它们难以或无法读取 Example 有没有办法设置每个误差条的位置 即沿 x 轴移动它 以便重叠的线显示在彼此
  • OpenCV Python cv2.mixChannels()

    我试图将其从 C 转换为 Python 但它给出了不同的色调结果 In C Transform it to HSV cvtColor src hsv CV BGR2HSV Use only the Hue value hue create
  • 使用 matplotlib 绘制时间序列数据并仅在年初显示年份

    rcParams date autoformatter month b n Y 我正在使用 matpltolib 来绘制时间序列 如果我按上述方式设置 rcParams 则生成的图会在每个刻度处标记月份名称和年份 我怎样才能将其设置为仅在每
  • PyUSB 1.0:NotImplementedError:此平台不支持或未实现操作

    我刚刚开始使用 pyusb 基本上我正在玩示例代码here https github com walac pyusb blob master docs tutorial rst 我使用的是 Windows 7 64 位 并从以下地址下载 z
  • 根据列值突出显示数据框中的行?

    假设我有这样的数据框 col1 col2 col3 col4 0 A A 1 pass 2 1 A A 2 pass 4 2 A A 1 fail 4 3 A A 1 fail 5 4 A A 1 pass 3 5 A A 2 fail 2
  • 如何从网页中嵌入的 Tableau 图表中抓取工具提示值

    我试图弄清楚是否有一种方法以及如何使用 python 从网页中的 Tableau 嵌入图形中抓取工具提示值 以下是当用户将鼠标悬停在条形上时带有工具提示的图表示例 我从要从中抓取的原始网页中获取了此网址 https covid19 colo
  • SQLALchemy .query:类“Car”的未解析属性引用“query”

    我有一个这里已经提到的问题https youtrack jetbrains com issue PY 44557 https youtrack jetbrains com issue PY 44557 但我还没有找到解决方案 我使用 Pyt
  • Spark KMeans 无法处理大数据吗?

    KMeans 有几个参数training http spark apache org docs latest api python pyspark mllib html highlight kmeans pyspark mllib clus
  • Python 函数可以从作用域之外赋予新属性吗?

    我不知道你可以这样做 def tom print tom s locals locals def dick z print z name z name z guest Harry print z guest z guest print di
  • 如何加速Python中的N维区间树?

    考虑以下问题 给定一组n间隔和一组m浮点数 对于每个浮点数 确定包含该浮点数的区间子集 这个问题已经通过构建一个解决区间树 https en wikipedia org wiki Interval tree 或称为范围树或线段树 已经针对一
  • 如何使用 OpencV 从 Firebase 读取图像?

    有没有使用 OpenCV 从 Firebase 读取图像的想法 或者我必须先下载图片 然后从本地文件夹执行 cv imread 功能 有什么办法我可以使用cv imread link of picture from firebase 您可以
  • Pygame:有没有简单的方法可以找到按下的任何字母数字的字母/数字?

    我目前正在开发的游戏需要让人们以自己的名义在高分板上计时 我对如何处理按键有点熟悉 但我只处理过寻找特定的按键 有没有一种简单的方法可以按下任意键的字母 而不必执行以下操作 for event in pygame event get if
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i
  • 对年龄列进行分组/分类

    我有一个数据框说df有一个柱子 Ages gt gt gt df Age 0 22 1 38 2 26 3 35 4 35 5 1 6 54 我想对这个年龄段进行分组并创建一个像这样的新专栏 If age gt 0 age lt 2 the
  • 有人用过 Dabo 做过中型项目吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我们正处于一个新的 ERP 风格的客户端 服务器应用程序的开始阶段 该应用程序是作为 Python 富客户端开发的 我们目前正在评估 Dabo
  • Conda SafetyError:文件大小不正确

    使用创建 Conda 环境时conda create n env name python 3 6 我收到以下警告 Preparing transaction done Verifying transaction SafetyError Th
  • Python:如何将列表列表的元素转换为无向图?

    我有一个程序 可以检索 PubMed 出版物列表 并希望构建一个共同作者图 这意味着对于每篇文章 我想将每个作者 如果尚未存在 添加为顶点 并添加无向边 或增加每个合著者之间的权重 我设法编写了第一个程序 该程序检索每个出版物的作者列表 并
  • Python 类继承 - 诡异的动作

    我观察到类继承有一个奇怪的效果 对于我正在处理的项目 我正在创建一个类来充当另一个模块的类的包装器 我正在使用第 3 方 aeidon 模块 用于操作字幕文件 但问题可能不太具体 以下是您通常如何使用该模块 project aeidon P
  • 导入错误:没有名为 site 的模块 - mac

    我已经有这个问题几个月了 每次我想获取一个新的 python 包并使用它时 我都会在终端中收到此错误 ImportError No module named site 我不知道为什么会出现这个错误 实际上 我无法使用任何新软件包 因为每次我

随机推荐

  • 统计学习方法学习梳理(一)统计学习的分类

    目录 1 基本分类 1 监督学习 2 无监督学习 3 强化学习 4 半监督学习 5 主动学习 2 按模型分类 1 概率模型与非概率模型 2 线性模型与非线性模型 3 参数化模型与非参数化模型 3 按算法分类 1 在线学习 2 批量学习 4
  • 为什么区块链宠物得到这么多资本家的青睐?

    区块链宠物最早进入人们视野是一款由Axiom Zen和以太坊智能合作开发的区块链宠物养成游戏 谜恋猫 也有人称其为加密猫 这款游戏基于以太坊产生 通过以太坊区块链上的智能合约进行追踪 用户需使用以太币购买猫咪 并通过智能合约自动分配 每15
  • typora的使用

    typora的使用 1 换行的实现 在一行的结尾加上两个空格实现换行 在两行之间加回车实现换行 2 标题 多少个 就多少级标题 一共六级标题 记得输完 要加空格 1 2 3 4 5 6 3 分割线 就出现分割线 要回车 4 强调 斜体 字体
  • numpy 寻找两个二维数组中重复的行(附代码)

    numpy 两个 N M 维度的 二维数组a 和 b 以行为单位 找到 a 和 b 中都存在的行 相同的行不一定出现在同一行的位置 通过遍历每一行寻找 import numpy as np 创建两个示例数组 a sorted np arra
  • 玩转触发器之Jenkins Generic Webhook使用技巧

    1 预备知识 目标 学习HTTP基础知识 掌握如何使用Postman和Curl调用接口的方法 1 1 Web HTTP基础知识 HTTP请求是什么 HTTP超文本传输协议 是确保服务器 Server 和客户端 Client 之间的正确通信
  • php同时作为server端和client端(soapclient)的超时时间设置小结

    http blog sina com cn s blog 475429950101bt7x html 场景 A通过HTTP请求B 同时B通过soap请求C webservice 然后B得到C的返回内容后 再响应回A client A gt
  • Linux系统编程——线程

    Linux系统编程 线程 1 线程概述 与进程的区别及线程的优势 2 线程创建等待退出 3 线程共享内存空间的代码验证 4 线程同步之互斥量加锁解锁 5 互斥锁限制共享资源的访问 6 什么情况造成死锁 7 线程条件控制实现线程的同步 1 线
  • 【基于Arduino的蓝牙控制小车】3D+电路图+控制代码详解

    更好的阅读体验 目录 1 环境搭建 1 1 电路模拟环境 3D建模环境 1 2蓝牙小车控制代码环境 2 Arduino串口通信 2 1 Arduino串口 2 2 系统函数 2 3 串口函数 2 3 1 Serial begin 2 3 2
  • STM32 websocket,TCP和UDP的传输速率

    网络上经常有人提到websocket TCP和UDP 的差别 说的大都是协议之间的差别 没有提及它们的传输能力 为了设计高吞吐量的物联网微服务器 最近对websocket TCP UDP的传输能力做了测试 使用STM32F746 处理器 操
  • 建立自己的机械臂–编程

    现在 手臂已经组装好了 是时候将其提升到一个新的水平了 现在是释放野兽并完全控制整个机器人手臂的时候了 在这篇文章的结尾 您应该对如何对该机械臂进行编程以完成您想要的事情有一个想法 要了解我如何到达这里 请访问我以前的文章 该文章描述了组装
  • Library\PackageCache\com.unity Error (are you missing a using directive or an assembly reference?)

    Library PackageCache com unity cinemachine 2 2 7 Runtime Timeline CinemachineTrack cs 16 6 error CS0246 The type or name
  • PAT考试 一日游记

    今天下午去考了PAT 真的很懵逼 首先 编译器炸了 弄了一个小时多的编译器 早知道就先不点击开始了 然后就是遇到了头文件CB不能调试 主要是用了unorder map unorder set 习惯性写的头文件 开局先默写头文件 然后就这样
  • MFC菜单的使用

    1 创建弹出菜单 1 利用向导 创建一个基于单文档的应用程序 2 在资源视图中选中 menu 鼠标右键插入一新菜单IDR POPMENU 3 在IDR POPMENU菜单中添加 弹出菜单 选项 在 弹出菜单 下添加菜单命令 复制 粘贴 查找
  • getResourceAsStream方法及缓存问题

    缓存问题 getResourceAsStream会先到缓存中读取文件 若缓存中没有 才会到真正的路径下去读取文件 所以用getResourceAsStream方法获取配置文件时 获取的不是最新配置 可以使用以下方法代替 该方法直接读文件 所
  • 算法(63)-二叉树的递归-搜索二叉树-满二叉树-平衡二叉树-

    目录 1 二叉树 2 搜索二叉树 3 满二叉树 4 平衡二叉树 1 二叉树 先 中 后序遍历 先序 中 左 右 1 2 4 5 3 6 7 中序 左 中 右 4 2 5 1 6 3 7 后序 左 右 中 4 5 2 6 7 3 1 void
  • 【推荐算法】推荐系统的评估

    一 离线评估的主要方法 1 Holdout检验 Holdout检验是基础的离线评估方法 它将原始的样本集合随机划分为训练集和验证集两部分 比如70 训练集 30 测试集 但现在很多机器学习框架 深度学习框架中都增加了验证集 即将整个数据集分
  • python创建sqlite3 unicode error_在python2.7.3中使用sqlite3的Unicode

    我试图插入到一个表中 但似乎我打开的文件中有非ascii字符 这是我得到的错误 sqlite3 ProgrammingError You must not use 8 bit bytestrings unless you use a tex
  • IDEA捕获异常快捷键(try/catch……)

    捕获异常 这时候快捷键的时候就可以事半功倍 ctrl alt t
  • 每日10行代码125: 用python计算快乐8一等奖的中奖概率

    先简单介绍下快乐8一等奖的规则 投注人从80个数中选10个 开奖时会从80个数中开出20个 如果选择的10个数均在开出的20个数中 那么就是中一等奖 也叫选十中十 那么中一等奖的概率是多少呢 这其实是数学中的概率问题 解题方法 选求所有可能
  • Python算法:动态规划

    转载自伯乐在线 本节主要结合一些经典的动规问题介绍动态规划的备忘录法和迭代法这两种实现方式 并对这两种方式进行对比 大家都知道 动态规划算法一般都有下面两种实现方式 前者我称为递归版本 后者称为迭代版本 根据前面的知识可知 这两个版本是可以