说说回溯2

141 阅读2分钟

说说回溯

说说回溯

  • 还是以递归那个最简单1到100的累加为例
def f(x):
    global sum
    if x == 0:
        return 0
    else:
        sum = f(x - 1) + x
        sum = sum - x
        print sum
        return sum
print '===='
print(f(100))
print '-----'

以这个代码为例,因为这里的累加是递归到0之后返回然后从0累加到100,而回溯是返回时,也就是返回时+x同时又-x 所以结果是0

全排列的回溯

#!/usr/bin/env python
# -*- coding: utf-8 -*-#

#-------------------------------------------------------------------------------
# Name:         test_traceback
# Description:
# Author:       handa
# Date:         2022/1/13
#-------------------------------------------------------------------------------
import copy
numlist = [1,2,3]

container = []
all=[]
def traceback(numlist):
    for i in numlist:
        #print i
        if len(container) == 3:
            print 'the size is ready '
            print container
            new = copy.deepcopy(container)
            all.append(new)
            print all
            return
        if i in container:
            print 'i:%s has in list' %(i)
            continue
        else:
            print 'append %s' %(i)
            container.append(i)
        print 'start call fun trackback:'
        traceback(numlist)
        print 'before the traceback container value is:%s' %(container)
        t = container.pop()
        print 'after the traceback pop the value is: %s, container value is: %s' %(t,container)
        print 'after the traceback the container :%s' %(container)
        
        
//全排列是多路选择,迭代和递归相互螺旋叠加调用,所以看起来情况比较复杂。
迭代调用递归,递归又调用迭代中的递归

它整体的执行特性有几个特点:多路迭代调用递归并发执行、螺旋向下递归,并且部分迭代并发递归是被阻塞在递归调用里,得等回溯了才能继续执行。

比如: 当numlist= [1,2,3]
    for i in numlist:
        if i in container:
            print 'i:%s has in list' %(i)
            continue
        else:
            print 'append %s' %(i)
            container.append(i)
        print 'start call fun trackback:'
        traceback(numlist)
        
     

每次多路选择的迭代都会递归同样的numlist序列。
在递归的逻辑里我们加了递归的过滤条件和终止条件,当不符合过滤条件则进行递归,这时迭代的递归会因为向下递归的逻辑没执行后,后续的迭代序列递归被阻塞在先前的序列递归上,只有等整个函数回溯了才得已继续。

比如for i in [1,2,3] 当2满足不在container条件,这时container.append(2),继续走traceback(numlist).向下递归,同时阻塞[1,2,3]序列的3
只有当满足if len(container) == 3:条件时,才会进行回溯,回溯时会执行container.pop(),并且还会回到刚刚阻塞的迭代序列里继续执行。

当满足if len(container) == 3时,container.pop(3),然后又pop(2),继续执行for i in [1,2,3](此时i=3).

这也说明了为什么组合里有123还能有132132由两块逻辑共同完成,一块是回溯的pop逻辑,一块是多路选择的迭代组合(因为前面的迭代被阻塞,返回时继续)







代码图示

wpsDC4F.tmp.jpg