概率图模型

本文主要是对网上的一些文章的总结,参考的文章在文末已经列出
音频信号是模拟信号,我们需要将其保存为数字信号,才能对语音进行算法操作,WAV 是 Microsoft 开发的一种声音文件格式,通常被用来保存未压缩的声音数据。
语音信号有三个重要的参数:声道数、取样频率和量化位数。
如果你需要自己录制和编辑声音文件,推荐使用 Audacity (http://audacity.sourceforge.net), 它是一款开源的、跨平台、多声道的录音编辑软件。
这个问题和斐波纳契数字问题是一样的。题目描述如下:
一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
首先用递归的思路来考虑。递归是倒着分析的。
假如只差一步就能走完整个台阶,要分为几种情况?因为每一步能走一级或者两级台阶,所以有如下两种情况:
所以第 n 步的走法由两种方法的和构成。如果定义 F (n) 为第 n 步的走法,那么 F (n)=F (n-1)+F (n-2)。这个公式称之为递推公式。
当只有 1 级台阶和 2 级台阶时走法很明显,即 F (1)=1、F (2)=2。称之为边界条件。
两部分具备之后,很容易可以写出代码:
1 | def fun(n): |
我们不妨把上面的递归式子以树的形式表示出来,结果如下:
1 | F(5) |
记忆化搜索的思路如下:每当我们需要解决子问题时,我们首先查找查找表。如果预先计算的值存在,那么我们返回该值,否则我们计算值,并将结果放在查找表中,以便以后可以重复使用。
1 | lookup = [0,1,2]+[0]*100 |
LRU(Least recently used,最近最少使用),其核心思想是 “如果数据最近被访问过,那么将来被访问的几率也更高”。对于本题目,如果是高频出现的计算函数的结果会被放到缓存中,再次出现只需要在缓存中读取即可,和记忆化搜索类似。python 有 LRU 的内置函数:
1 | from functools import lru_cache |
有了上诉方法,n=100 已经可以计算了。但是虽然有这两个缓解的方法,但是仍存在问题。当 n=1000 的时候仍然会存在堆栈溢出的问题。
上面的思考都是基于递归的,即自顶而下的计算方法。如果我们换个思路,自底而上呢?
其实和上面的记忆化搜索很像了。首选记录 n=1 的情况和 n=2 的情况,然后依次向上计算,每次计算都存表即可。
1 | N = 10 |
这种方法存的表称之为 DP Table, 这种解决思路称之为动态规划。本题目的 DP Table 是一维的,所以称之为一维动态规划。
当然针对这个问题,对空间还可以进一步优化:
1 | def fun(n): |
上面我们已经见到过了:递归采用的是 “由上而下” 的解题策略并带有可能的” 子问题 “重复调用,时间复杂度自然高,而且容易造成堆栈的溢出。
两者的区别在于:动态规划的下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解。
贪心算法每走一步都是不可撤回的,而动态规划是在一个问题的多种策略中寻找最优策略,所以动态规划中前一种策略可能会被后一种策略推翻。
具体参考 文章
1 | import bisect |