使用二叉树搜索(DFS、BFS和隐式搜索)求解背包问题
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)
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:])
here = BinaryTree(sofar)
here.set_left_branch(with_it)
here.set_right_branch(without_it)
return here
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():
a = [
6,
3]
b = [
7,
2]
c = [
8,
4]
d = [
9,
5]
e = [
12,
4]
d_tree = build_D_tree([], [a, b, c, d, e])
print(
"-------- Using DFS -----------")
foo = DFS_D_tree(d_tree, sum_values, weights_below10)
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函数可以改变背包的重量限制