递归三定律
- 必须有一个基本结束条件(对最小规模问题的直接解决)
- 必须能改变状态向基本结束条件严禁(减小问题规模)
- 必须调用自身(把问题分解成规模更小的相同问题)
递归为自顶向下求解,把最大规模逐步分解为小规模。
递归深度限制
python中可用内置sys模块获取和调整最大递归深度
>>>import sys
>>>sys.getrecursionlimit()
1000
>>>sys.setrecursionlimit(3000)
>>>sys.getrecursionlimit()
3000
分治策略
将问题分为若干更小规模的部分,通过解决每一个小规模的问题,将结果汇总得到原问题的解。
贪心策略
例如:自动售货机在找零时,如何吐出不同面值的硬币,能够找给顾客最少的硬币数量?
贪心策略:每次都试图解决问题的尽量大的一部分。每次以最多数量的最大面值来迅速减少找零面值。即先把面值最大硬币的兑换完,找不开的再用次大面值的找。
但贪心策略不一定是最优解!
比如硬币为25c,21c,10c,1c,要找零63c。贪心策略的解法为:63=25x2+10x1+1x3,但最优解为63=21x3…
递归可视化
python内置海龟作图系统 turtle module
主要函数有:
爬行:forward(n); backward(n)
转向:left(n); right(n)
抬笔放笔:penup(); pendown()
笔属性:pensize(s);pencolor(c)
使用方法见应用3,4,5
动态规划
最优化问题能够用动态规划的条件:原始问题的最优解包含了更小规模问题的最优解。从最简单的优化问题开始,比如硬币面值为1c,2c,求出找零1c的最优解best1c=1,best2c=1,则best3c=min(1+best2c, 2+best1c)=2, best4c=min(1+best3c,2+best2c)=3,依次累加上去。
动态规划为自底向上求解,即先计算最小规模的结果,然后逐渐累加上去,直到求到最大规模。
使用方法见应用8,9
应用
- 数列求和
def listsum(numlist):
#基本结束条件
if len(numlist)==1:
return numlist[0]
#调用自身
else:
return numlist[0]+listsum(numlist[1:])#减小问题规模
alist=[1,2,5,6,8]
a=listsum(alist)
- 将10进制转换为任意进制
strs=['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
def shift(num,jinzhi):
if num<jinzhi:
return strs[num]
return shift(num//jinzhi,jinzhi)+str(strs[num%jinzhi])
a=shift(1453,16) #5AD
- 画一个螺旋线。最大长度为100,然后每转向一次长度减5,直到长度小于0为止。
import turtle
t=turtle.Turtle()
def drawSpiral(length):
if length<0:
return
t.forward(length)
t.right(90)
drawSpiral(length-5)
drawSpiral(100)
turtle.done()
结果如下。
- 分形树:自相似递归图形
import turtle
def tree(branch_len):