二叉树搜索求解背包问题

使用二叉树搜索(DFS、BFS和隐式搜索)求解背包问题
# -*- coding: utf-8 -*-

# general binary-tree
class BinaryTree:

    def __init__(self, value):
        self._value       = value
        self._parent_node = None
        self._left_node   = None
        self._right_node  = None

    def get_right_branch(self):
        return self._right_node

    def get_left_branch(self):
        return self._left_node

    def get_parent_branch(self):
        return self._parent_node

    def set_right_branch(self, node):
        self._right_node = node

    def set_left_branch(self, node):
        self._left_node = node

    def set_parent_branch(self, node):
        self._parent_node = node

    def get_value(self):
        return self._value

    def set_value(self, value):
        self._value = value

    def __str__(self):
        return "Node Value: {}".format(self._value)

# build Decision-Tree for knapsack problem
def build_D_tree(sofar, todo):
    if len(todo) == 0:
        return BinaryTree(sofar)
    else:
        with_it = build_D_tree(sofar + [todo[0]], todo[1:])
        without_it = build_D_tree(sofar, todo[1:])
        # current node
        here = BinaryTree(sofar)
        # link left node <with it>
        here.set_left_branch(with_it)
        # link right node <without it>
        here.set_right_branch(without_it)
        return here

# solve knapsack problem by searching Decison-Tree 
def DFS_D_tree(root, value_func, constrain_func):
    stack = [root]
    best = None
    visited = 0
    while len(stack) > 0:
        visited += 1
        if constrain_func(stack[0].get_value()):
            if best == None:
                best = stack[0]
            elif value_func(stack[0].get_value()) > value_func(best.get_value()):
                best = stack[0]
            temp = stack.pop(0)
            if temp.get_right_branch():
                stack.insert(0, temp.get_right_branch())
            if temp.get_left_branch():
                stack.insert(0, temp.get_left_branch())
        else:
            stack.pop(0)
    print("visited: {}".format(visited))
    return best

def BFS_D_tree(root, value_func, constrain_func):
    queue = [root]
    best = None
    visited = 0
    while len(queue) > 0:
        visited += 1
        if constrain_func(queue[0].get_value()):
            if best == None:
                best = queue[0]
            elif value_func(queue[0].get_value()) > value_func(best.get_value()):
                best = queue[0]
            temp = queue.pop(0)
            if temp.get_right_branch():
                queue.append(temp.get_right_branch())
            if temp.get_left_branch():
                queue.append(temp.get_left_branch())
        else:
            queue.pop(0)
    print("visited: {}".format(visited))
    return best

def DTree_implicit_search(to_consider, avail):
    if to_consider == [] or avail == 0:
        result = (0, ())
    elif to_consider[0][1]> avail:
        result = DTree_implicit_search(to_consider[1:], avail)
    else:
        next_item = to_consider[0]
        with_val, with_to_take = DTree_implicit_search(to_consider[1:], avail - next_item[1])
        with_val += next_item[0]
        without_val, without_to_take = DTree_implicit_search(to_consider[1:], avail)
        if with_val > without_val:
            result = (with_val, with_to_take + (next_item, ))
        else:
            result = (without_val, without_to_take)
    return result

def sum_values(lst):
    vals = [e[0] for e in lst]
    return sum(vals)

def weights_below10(lst):
    wts = [e[1] for e in lst]
    return sum(wts) <= 10

def main():
    # the value of things and their weight
    a = [6, 3]
    b = [7, 2]
    c = [8, 4]
    d = [9, 5]
    e = [12, 4]

    # build D-Tree
    d_tree = build_D_tree([], [a, b, c, d, e])
    print("-------- Using DFS -----------")
    # search by DFS
    foo = DFS_D_tree(d_tree, sum_values, weights_below10)
    # output things in the knapsack
    print(foo.get_value())
    print("-------- Using BFS -----------")
    foo = BFS_D_tree(d_tree, sum_values, weights_below10)
    print(foo.get_value())
    print("-------- Implicit search -----")
    foo = DTree_implicit_search([a, b, c, d, e], 10)
    print(foo)
if __name__ == "__main__":
    main()
Note
更改weights_below10函数可以改变背包的重量限制
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值