我遇到了一个名为Knapsack的有趣问题。你有一个项目列表,它们都有一个值和一个权重。然后,您必须找到最大化对象总和值的项目组合,并保持在一定限度内。我在某处看到这是一个搜索问题,您可以使用不同的搜索算法。现在我试图用广度优先实现它。
在维基百科上找到的BFS伪算法如下:
Breadth-First-Search(Graph, root):
create empty set S
create empty queue Q
root.parent = NIL
Q.enqueue(root)
while Q is not empty:
current = Q.dequeue()
if current is the goal
return current
for each node n that is adjacent to current:
if n is not in S:
add n to S
n.parent = current
Q.enqueue(n)
我真的试图了解如何将其应用于背包问题。
据我所知,这是关于建造一棵树。我需要一次扩展和探索一个级别的每个节点。对于BFS,我需要一个FIFO队列。对于每个选定的项目,我有两个选择:我是否采取该项目。 无论如何,具体来说:我不明白,在我的上下文中,上面的伪代码是:
答案 0 :(得分:0)
假设您有4个不同的项目。然后,您正在搜索的图表是这样的超立方体(图片来自Yury Chebiryak):
节点上的二进制数是所有可能的背包, n 中的0表示项目 n 不在背包中,并且1意思是,所以例如0000表示空背包,1001表示包含第一个项目和第4个项目的背包,依此类推。
在每个步骤中,您从队列中删除当前节点,如果它不是目标,则通过查找与当前逐个项目不同的所有背包来构建相邻节点。我已经去过了。因此,例如,如果当前节点为1001,则构建节点0001,1101,1011和1000.然后将这些节点添加到队列中。
如果你正在寻找一个足够好的目标,那么这个目标只有意义。解决方案,而不是最佳解决方案。要确定当前节点是否是目标,您只需计算当前背包的值并将其与目标值进行比较。
如果您想要最佳解决方案,那么广度优先搜索对您没有帮助,因为您需要浏览图表中的每个节点。 Dynamic programming或backtracking(这是一种Depth First Search)可以减少搜索空间。
如果你想要一个足够好的"解决方案,然后FIFO branch-and-bound或hill climbing(从随机背包开始)是使用广度优先搜索的有效方法。