pythonlistfor-loopknapsack-problembranch-and-bound

Selecting items with highest value in a list with the right order


I am solving a knapsack problem by using branch and bound algorithm I am working on right now. In the algorithm, I wanted to start selecting the items with the highest density(value/weight). I created a list named "density" and made necessary calculations. I need to pick the maximum value each time from that list. But everytime I try, the order get mixed. I need to update the variable "a" because everytime I delete an item the list gets one smaller. But couldn't figure out how to update it. I need help on selecting the items in the right order.

weight, value, density are lists. capacity and room are integer values given in the problem. This is the density list.

enter image description here

What I want is, to get the index of the maximum item in this list. Then, subtract the "weight" of it from the "capacity" in order to find how much "room" left. And add the "value" to the "highest" in order the reach the highest value could be added in the knapsack. After I did this for the first item, then iterate it until no or very little room left.

    def branch_n_bound(value,weight,capacity):
        global highest,size
        size=0
        room=capacity
        density = [0] * len(items)
        highest = 0
        for i in range(n):
            density[i] = val[i] / weight[i]
        for i in range(n):
            a=density.index(max(density))
            if weight[a]<=room:
                room-=weight[a]
                highest+=value[a]
                size+=weight[a]
                taken[a]=1
                del density[a], weight[a], value[a]
            else:
                break

Solution

  • I think the problem you try to solve can be solved easier with a change in data structure. Instead of building the density array, you can build an array of tuples [(density, weight, value)...] and base your solution over that array. If you don't want to use so much extra memory and assuming you are ok with changing the input data, you can mark your indices as deleted - for example, you can set the value, weight and density to something negative to know that data was deleted from that index.

    You can also take a look at the heapq data structure: https://docs.python.org/3/library/heapq.html . You can work with a heap to extract the maximum, and store indices in that heap.