简体   繁体   中英

Implement 0/1 knapsack problem in python using backtracking

I would like to display the maximum value possible given a Maxweigth and the indexes of items selected.
I would also like to count the number of recursive calls happening during the execution.

  • random weight and value lists are generated using the generate function.
  • vsol[] has the final list of item indexes selected
  • temp[] holds the temporarily selected indexes
  • values[] will hold the array of values of items
  • weights[] will hold the array of weights of items
  • solution after the Knapsack() will hold the max value it can have from the given weight(second argument of Knapsack()) 在此处输入图像描述 input : values[] = [60,100,120], weights[10,20,30], maxWeigth = 50
    Expected Output : 220 [1,2]
    output sited : 0 [] for every input selected item indexes
import random
import copy

weights = []
values = []
temp = []
vsol = []
isSol = False
solution = 0
def Knapsack(i,max,value):
    for k in range(i,len(values)):
        if max > 0:
            if weights[k] <= max:
                temp.append(k);
                if (value+values[k] >= solution):
                    solution = value+values[k];
                    isSol = True
            if (k+1)<n:
                Knapsack(k+1,max-weight[k],value+values[k])
            else:
                if isSol == True:
                    vsol = []
                    vsol = copy.deepcopy(temp)
                    temp = []
                    isSol = False
                else:
                    temp = []
                    return
        else:
            if isSol == True:
                vsol = []
                vsol = copy.deepcopy(temp)
                temp = []
                isSol = False
            else:
                temp = []
                return
    
    

def generator(n):
    l = [];
    for i in range(n):
        l.append(random.randint(1,100))
    return l    
def main():
    n = 10 #number of random numbers
    weights = generator(n);
    values = generator(n);
    Knapsack(0,10,0)
    print(solution,vsol)
    
main()

I tried deep copying the temp list to vsol[].

import sys
import math
sys.setrecursionlimit(10**8)

c = 0
def knapSack(mW,w,v,n):
    # counter how many time recursive function is called.
    global c
    c += 1
    
    if(mW == 0 or n == 0):
        return [0,[]]
        
    if(w[n-1] > mW):
        return knapSack(mW,w,v,n-1)
        
    set1 = knapSack(mW-w[n-1],w,v,n-1)
    set2 = knapSack(mW,w,v,n-1)
    
    if(set1[0]+v[n-1] > set2[0]):
        set1[1].append(n-1)
        set1[0] += v[n-1]
        return set1
    else:
        return set2
        
val = [160, 100, 120]
wt = [10, 20, 30]
W = 50
n = len(val)
print("Knapsack Max & list:",knapSack(W, wt, val, n))
print("Total Recursive Steps: ",c)
    

Python tutor : use this simulator in future to learn what is happening.

Hi i update your code in python3 with true main function and get indexes and values in knapsack function

use fullowing Code:

import random
import copy
import time


def Knapsack(i, max, value):
    range_size = len(values)
    global temp
    global solution
    global isSol
    global vsol
    global idx
    global final_idx
    for k in range(i, range_size):
        if max > 0:
            if weights[k] <= max:
                temp.append(k)
                if (value+values[k] >= solution):
                    solution = value+values[k]
                    vsol = copy.deepcopy(temp)
                    idx.append(vsol)
                    if len(idx) > 1:
                        if idx[0] != idx[-1-1]:
                            idx[-1-1].pop()
                        final_idx = idx[-1-1] + vsol
                    isSol = True
            if (k+1) < n:
                Knapsack(k+1, max-weights[k], value+values[k])
            else:
                if isSol == True:
                    temp = []
                    isSol = False
                else:
                    temp = []
                    # if max != 20:
                    #     vsol.pop(k-1)
                    return
        else:
            if isSol == True:
                temp = []
                isSol = False
            else:
                temp = []
                return


def generator(n):
    l = []
    for i in range(n):
        l.append(random.randint(1, 100))
    return l


if __name__ == '__main__':
    temp = []
    vsol = []
    idx = []
    final_idx = []
    isSol = False
    solution = 0

    weights = []
    values = []
    max_size = int(input("Enter your Max Weight: "))
    n = int(input("Enter your list item size: "))
    for _ in range(n):
        w = int((input('Enter weights: ')))
        weights.append(w)

    for _ in range(n):
        v = int((input('Enter values: ')))
        values.append(v)

    start_time = time.time()

    Knapsack(i=0, max=max_size, value=0)
    print('\n solution values : ', solution, '\n',
          'Selected Item index :', vsol, '\n', 'Selected Items :', final_idx)
    for value in final_idx:
        print(values[value])
    print("--- %s seconds ---" % (time.time() - start_time))

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