简体   繁体   中英

Problems with a branch and bound knapsack algorithm

I am working on a knapsack optimization exercise written in Python. The goal is to fill a knapsack with limited weight capacity with items with a certain value and weight resulting maximizing the total value of the knapsack. I ran into a problem with setting the variables when a better solution is found.

I've created a simplified version of the code without any constraints, demonstrating my problem. Since there are no constraints, the first solution is always the best solution since that is the solution where all items are taken.

There is an if statement in the code that sets the max_value and best_taken variables in case a better solution is found.

However: When the print statement at the end of the code prints the max_value and best_taken variables, the max_value shows the correct value (the sum of the first indices in the list of lists assigned to the items variable). The best_taken value always ends up as [0,0] where a value of [1,1] (=take both items) is expected.

What am I doing wrong?

items = [[5,3],[4,1]]
depth = 0


class BranchBound():
    def __init__(self):
        self.max_value = 0
        self.best_taken = []
        self.local_value = 0
        self.local_taken = [0] * len(items)
       
    
    def branch_and_bound(self,depth):
        new_depth = depth
        if new_depth < len(items):
            #Take item
            self.local_taken[new_depth] = 1           
            new_depth += 1
            self.branch_and_bound(new_depth)
            
            # Do not take item
            new_depth = depth
            self.local_taken[new_depth] = 0
            new_depth += 1
            self.branch_and_bound(new_depth)
        else:
            self.local_value = 0
            for i,j in zip(self.local_taken,items):
                self.local_value += i*j[0]
            if self.local_value > self.max_value:
                print("ping")
                self.max_value = self.local_value
                self.best_taken = self.local_taken
            
        
bb = BranchBound()
bb.branch_and_bound(depth)
print(bb.max_value)
print(bb.best_taken)

You need to copy local_taken . Assigning an array to an attribute just adds a reference to the same (mutable) array

self.best_taken = self.local_taken[:]

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