human
I am working on the file "0-1-Knapsack.ipynb".
The first task is:
简单解释一下，先对 <code>vw</code> 按照单位重量的价值排序，然后利用 <code>bound</code> 函数确定价值上限。如果价值上限超过了已经出现的最大价值，再分别计算加上当前物品和不加当前物品的两种情况，否则就跳过。
我们还拿前面的那个小例子来看，它执行过程可以用下面这个图来表示：
<img src="0-1-Knapsack/img/knapsack_tiny.png" alt="knapsack_tiny" width="245" height="281" class="aligncenter size-full wp-image-10196" />
显然这是一个深度优先搜索，图中每个结点分别列出了它的当前价值、当前重量和价值上限，红色结点表示重量超限，黄色结点表示价值上限不足，加粗的圈是最优解。这个树看起来比上面那个小多了吧！
如果包包大一点，效果就更明显了，比如这个<a href="0-1-Knapsack/test/knapsack_15.txt">有 15 个物品的包包</a>，它的搜索过程是这样的（点击看大图）：
<img src="0-1-Knapsack/img/knapsack_15.png" alt="knapsack_15" width="641" height="630" class="aligncenter size-full wp-image-10200" />
看看我们剪掉了多少红圈黄圈！看起来很不错，让我们来试试前面的那些大包包…… 诶怎么回事……
<pre class="toolbar:2 striped:false nums:false nums-toggle:false lang:default decode:true " >RuntimeError: maximum recursion depth exceeded while calling a Python object</pre>

好吧递归太深了……我们可以加大递归深度：
```python
import thread
...
def main():
...
if name == "main":
    threading.stack_size(67108864) # 64MB stack
    sys.setrecursionlimit(20000)
    thread = threading.Thread(target=main)
    thread.start()
```
在 Windows 下面递归深度除了受 recursion limit 约束，还受栈空间限制，所以这里用 <code>thread</code> 来设定栈空间，而它只对新建的线程有效。如果不扩大栈空间，2000 个项目还可以，10000 个就不行了。
当然，所有的递归都是可以解开的，为什么非要用递归呢！直接把后面待处理的结点压进栈里不就行了吗，当然要注意压栈的顺序变了：
Can you write Python code for it?
 What is a the Python code you requested?
assistant
#Here is the Python code you requested.

def knapsack(vw, limit):
    
    def bound(v, w, j):
        if j >= len(vw) or w > limit:
            return -1
        else:
            while j < len(vw) and w + vw[j][1] <= limit:
                v, w, j = v + vw[j][0], w + vw[j][1], j + 1
            if j < len(vw):
                v += (limit - w) * vw[j][0] / (vw[j][1] * 1.0)
            return v
    
    stack = [(0, 0, 0)]
    maxValue = -1
    while stack:
        v, w, j = stack.pop()
        if bound(v, w, j) >= maxValue:
            if j < len(vw) - 1: 
                stack.append([v, w, j + 1]) 
            if w + vw[j][1] <= limit:
                maxValue = max(maxValue, v + vw[j][0])
                stack.append([v + vw[j][0], w + vw[j][1], j + 1])
       
    return maxValue

if __name__ == "__main__":
    with open("0-1-Knapsack/test/knapsack_extra.txt") as f:
        limit, n = map(int, f.readline().split())
        vw = []                   # value, weight, value density
        for ln in f.readlines():
            vl, wl = tuple(map(int, ln.split()))
            vw.append([vl, wl, vl / (wl * 1.0)])

%time    print(knapsack(sorted(vw, key=lambda x : x[2], reverse=True), limit))