树:深度优先搜索、广度优先搜索、背包问题

来源:互联网 发布:java驻场开发 编辑:程序博客网 时间:2024/05/19 12:17

实现树,二叉树的类实现,并且演示深度优先搜索、广度优先搜索、背包问题等算法。

### decision trees and tree search### first version is just a binary treeclass binaryTree(object):    def __init__(self, value):        self.value = value        self.leftBranch = None        self.rightBranch = None        self.parent = None     def setLeftBranch(self, node):        self.leftBranch = node    def setRightBranch(self, node):        self.rightBranch = node    def setParent(self, parent):        self.parent = parent    def getValue(self):        return self.value    def getLeftBranch(self):        return self.leftBranch    def getRightBranch(self):        return self.rightBranch    def getParent(self):        return self.parent    def __str__(self):        return self.value    def DFSBinary(root, fcn):    queue = [root]    while len(queue) > 0:        print 'at node ' + str(queue[0].getValue())        if fcn(queue[0]):            return True        else:            temp = queue.pop(0)            if temp.getRightBranch():                queue.insert(0, temp.getRightBranch())            if temp.getLeftBranch():                queue.insert(0, temp.getLeftBranch())    return Falsedef BFSBinary(root, fcn):    queue = [root]    while len(queue) > 0:        print 'at node ' + str(queue[0].getValue())        if fcn(queue[0]):            return True        else:            temp = queue.pop(0)            if temp.getLeftBranch():                queue.append(temp.getLeftBranch())            if temp.getRightBranch():                queue.append(temp.getRightBranch())    return Falsedef DFSBinaryOrdered(root, fcn, ltFcn):    queue = [root]    while len(queue) > 0:        if fcn(queue[0]):            return True        elif ltFcn(queue[0]):            temp = queue.pop(0)            if temp.getLeftBranch():                queue.insert(0, temp.getLeftBranch())        else:            temp = queue.pop(0)            if temp.getRightBranch():                queue.insert(0, temp.getRightBranch())    return Falsen5 = binaryTree(5)n2 = binaryTree(2)n1 = binaryTree(1)n4 = binaryTree(4)n8 = binaryTree(8)n6 = binaryTree(6)n7 = binaryTree(7)n3 = binaryTree(3)n5.setLeftBranch(n2)n2.setParent(n5)n5.setRightBranch(n8)n8.setParent(n5)n2.setLeftBranch(n1)n1.setParent(n2)n2.setRightBranch(n4)n4.setParent(n2)n8.setLeftBranch(n6)n6.setParent(n8)n6.setRightBranch(n7)n7.setParent(n6)n4.setLeftBranch(n3)n3.setParent(n4)def find6(node):    return node.getValue() == 6def find10(node):    return node.getValue() == 10def find2(node):    return node.getValue() == 2def lt6(node):    return node.getValue() > 6# test examplesprint 'DFS'DFSBinary(n5, find6)print ''print 'BFS'BFSBinary(n5, find6)## if we wanted to return the path that got to the goal, would need to modifydef DFSBinaryPath(root, fcn):    queue = [root]    while len(queue) > 0:        if fcn(queue[0]):            return TracePath(queue[0])        else:            temp = queue.pop(0)            if temp.getRightBranch():                queue.insert(0, temp.getRightBranch())            if temp.getLeftBranch():                queue.insert(0, temp.getLeftBranch())    return Falsedef TracePath(node):    if not node.getParent():        return [node]    else:        return [node] + TracePath(node.getParent())print''print 'DFS path'pathTo6 = DFSBinaryPath(n5, find6)print [e.getValue() for e in pathTo6]## make a decision tree## for efficiency should really generate on the fly, but here will build## and then searchdef buildDTree(sofar, todo):    if len(todo) == 0:        return binaryTree(sofar)    else:        withelt = buildDTree(sofar + [todo[0]], todo[1:])        withoutelt = buildDTree(sofar, todo[1:])        here = binaryTree(sofar)        here.setLeftBranch(withelt)        here.setRightBranch(withoutelt)        return heredef DFSDTree(root, valueFcn, constraintFcn):    queue = [root]    best = None    visited = 0    while len(queue) > 0:        visited += 1        if constraintFcn(queue[0].getValue()):            if best == None:                best = queue[0]                print best.getValue()            elif valueFcn(queue[0].getValue()) > valueFcn(best.getValue()):                best = queue[0]                print best.getValue()            temp = queue.pop(0)            if temp.getRightBranch():                queue.insert(0, temp.getRightBranch())            if temp.getLeftBranch():                queue.insert(0, temp.getLeftBranch())        else:            queue.pop(0)    print 'visited', visited    return bestdef BFSDTree(root, valueFcn, constraintFcn):    queue = [root]    best = None    visited = 0    while len(queue) > 0:        visited += 1        if constraintFcn(queue[0].getValue()):            if best == None:                best = queue[0]                print best.getValue()            elif valueFcn(queue[0].getValue()) > valueFcn(best.getValue()):                best = queue[0]                print best.getValue()            temp = queue.pop(0)            if temp.getLeftBranch():                queue.append(temp.getLeftBranch())            if temp.getRightBranch():                queue.append(temp.getRightBranch())        else:            queue.pop(0)    print 'visited', visited    return best  a = [6,3]b = [7,2]c = [8,4]d = [9,5]treeTest = buildDTree([], [a,b,c,d])def sumValues(lst):    vals = [e[0] for e in lst]    return sum(vals)def sumWeights(lst):    wts = [e[1] for e in lst]    return sum(wts)def WeightsBelow10(lst):    return sumWeights(lst) <= 10def WeightsBelow6(lst):    return sumWeights(lst) <= 6print ''print 'DFS decision tree'foobar = DFSDTree(treeTest, sumValues, WeightsBelow10)print foobar.getValue()print ''print 'BFS decision tree'foobarnew = BFSDTree(treeTest, sumValues, WeightsBelow10)print foobarnew.getValue()def DFSDTreeGoodEnough(root, valueFcn, constraintFcn, stopFcn):    stack = [root]    best = None    visited = 0    while len(stack) > 0:        visited += 1        if constraintFcn(stack[0].getValue()):            if best == None:                best = stack[0]                print best.getValue()            elif valueFcn(stack[0].getValue()) > valueFcn(best.getValue()):                best = stack[0]                print best.getValue()            if stopFcn(best.getValue()):                print 'visited', visited                return best            temp = stack.pop(0)            if temp.getRightBranch():                stack.insert(0, temp.getRightBranch())            if temp.getLeftBranch():                stack.insert(0, temp.getLeftBranch())        else:            stack.pop(0)    print 'visited', visited    return bestdef BFSDTreeGoodEnough(root, valueFcn, constraintFcn, stopFcn):    queue = [root]    best = None    visited = 0    while len(queue) > 0:        visited += 1        if constraintFcn(queue[0].getValue()):            if best == None:                best = queue[0]                print best.getValue()            elif valueFcn(queue[0].getValue()) > valueFcn(best.getValue()):                best = queue[0]                print best.getValue()            if stopFcn(best.getValue()):                print 'visited', visited                return best            temp = queue.pop(0)            if temp.getLeftBranch():                queue.append(temp.getLeftBranch())            if temp.getRightBranch():                queue.append(temp.getRightBranch())        else:            queue.pop(0)    print 'visited', visited    return bestdef atLeast15(lst):    return sumValues(lst) >= 15print ''print 'DFS decision tree good enough'foobar = DFSDTreeGoodEnough(treeTest, sumValues, WeightsBelow10,                                   atLeast15)print foobar.getValue()print ''print 'BFS decision tree good enough'foobarnew = BFSDTreeGoodEnough(treeTest, sumValues, WeightsBelow10,                                      atLeast15)print foobarnew.getValue()def DTImplicit(toConsider, avail):    if toConsider == [] or avail == 0:        result = (0, ())    elif toConsider[0][1] > avail:        result = DTImplicit(toConsider[1:], avail)    else:        nextItem = toConsider[0]        withVal, withToTake = DTImplicit(toConsider[1:], avail - nextItem[1])        withVal += nextItem[0]        withoutVal, withoutToTake = DTImplicit(toConsider[1:], avail)        if withVal > withoutVal:            result = (withVal, withToTake + (nextItem,))        else:            result = (withoutVal, withoutToTake)    return resultstuff = [a,b,c,d]val, taken = DTImplicit(stuff, 10)print ''print 'implicit decision search'print 'value of stuff'print valprint 'actual stuff'print takendef DFSBinaryNoLoop(root, fcn):    queue = [root]    seen = []    while len(queue) > 0:        print 'at node ' + str(queue[0].getValue())        if fcn(queue[0]):            return True        else:            temp = queue.pop(0)            seen.append(temp)            if temp.getRightBranch():                if not temp.getRightBranch() in seen:                    queue.insert(0, temp.getRightBranch())            if temp.getLeftBranch():                if not temp.getLeftBranch() in seen:                    queue.insert(0, temp.getLeftBranch())    return False##comment outn3.setLeftBranch(n5)n5.setParent(n3)# run DFSBinary(n5, find6)                                         

运行结果:



来自MIT MOOC课件

0 0