简体   繁体   中英

What's the time complexity of branch and bound approach to knapsack

I try to implement the branch and bound approach to knapsack problem with Python .

def bound(vw, v, w, idx):
    if idx >= len(vw) or w > limit:
        return -1
    else:
        while idx < len(vw) and w + vw[idx][1] <= limit:
            v, w, idx = v+vw[idx][0], w+vw[idx][1], idx + 1
        if idx < len(vw):
            v += (limit - w)*vw[idx][0]/(vw[idx][1] * 1.0)
        return v

def knapsack(vw, limit, curValue, curWeight, curIndex):
    global maxValue
    if bound(vw, curValue, curWeight, curIndex) >= maxValue:
        if curWeight + vw[curIndex][1] <= limit:
            maxValue = max(maxValue, curValue + vw[curIndex][0])
            knapsack(vw, limit, curValue + vw[curIndex][0], curWeight + vw[curIndex][1], curIndex+1)
    if curIndex < len(vw) - 1:
            knapsack(vw, limit, curValue, curWeight, curIndex+1)
    return maxValue

maxValue = 0

def test():
    with open(sys.argv[1] if len(sys.argv) > 1 else sys.exit(1)) as f:
    limit, n = map(int, f.readline().split())
    vw = []
    for ln in f.readlines():
        vl, wl = map(int, ln.split())
        vw.append([vl, wl, vl/(wl*1.0)])
    knapsack(sorted(vw, key=lambda x: x[2], reverse=True), limit) 

Here I have two questions:

  • What's the time complexity of the above codes?
  • Any improvement or optimization of the above codes?

As a general rule, CS theorists have found branch-and-bound algorithms extremely difficult to analyse: see eg here for some discussion. You can always take the full-enumeration bound, which is usually simple to calculate -- but it's also usually extremely loose.

I found it could be optimized with priority-queue

def knapsack(vw, limit):
    maxValue = 0
    PQ = [[-bound(0, 0, 0), 0, 0, 0]]
    while PQ:
        b, v, w, j = heappop(PQ)
        if b <= -maxValue:
            if w + vw[j][1] <= limit:
                maxValue = max(maxValue, v + vw[j][0])
                heappush(PQ, [-bound(v+vw[j][0], w+vw[j][1], j+1),
                                    v+vw[j][0], w+vw[j][1], j+1])
            if j < len(vw) - 1:
                heappush(PQ, [-bound(v, w, j+1), v, w, j+1])
    return maxValue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM