└── 0-1 Knapsack.py /0-1 Knapsack.py: -------------------------------------------------------------------------------- 1 | 2 | n = 4 3 | W = 16 4 | p = [40, 30, 50, 10] 5 | w = [2, 5, 10, 5] 6 | p_per_weight = [20, 6, 5, 2] 7 | 8 | 9 | class Priority_Queue: 10 | def __init__(self): 11 | self.pqueue = [] 12 | self.length = 0 13 | 14 | def insert(self, node): 15 | for i in self.pqueue: 16 | get_bound(i) 17 | i = 0 18 | while i < len(self.pqueue): 19 | if self.pqueue[i].bound > node.bound: 20 | break 21 | i+=1 22 | self.pqueue.insert(i,node) 23 | self.length += 1 24 | 25 | def print_pqueue(self): 26 | for i in list(range(len(self.pqueue))): 27 | print ("pqueue",i, "=", self.pqueue[i].bound) 28 | 29 | def remove(self): 30 | try: 31 | result = self.pqueue.pop() 32 | self.length -= 1 33 | except: 34 | print("Priority queue is empty, cannot pop from empty list.") 35 | else: 36 | return result 37 | 38 | class Node: 39 | def __init__(self, level, profit, weight): 40 | self.level = level 41 | self.profit = profit 42 | self.weight = weight 43 | self.items = [] 44 | 45 | 46 | def get_bound(node): 47 | if node.weight >= W: 48 | return 0 49 | else: 50 | result = node.profit 51 | j = node.level + 1 52 | totweight = node.weight 53 | while j <= n-1 and totweight + w[j] <= W: 54 | totweight = totweight + w[j] 55 | result = result + p[j] 56 | j+=1 57 | k = j 58 | if k<=n-1: 59 | result = result + (W - totweight) * p_per_weight[k] 60 | return result 61 | 62 | 63 | nodes_generated = 0 64 | pq = Priority_Queue() 65 | 66 | v = Node(-1, 0, 0) 67 | nodes_generated+=1 68 | maxprofit = 0 69 | v.bound = get_bound(v) 70 | 71 | 72 | 73 | pq.insert(v) 74 | 75 | while pq.length != 0: 76 | 77 | v = pq.remove() 78 | 79 | 80 | if v.bound > maxprofit: #check if node is still promising 81 | #set u to the child that includes the next item 82 | u = Node(0, 0, 0) 83 | nodes_generated+=1 84 | u.level = v.level + 1 85 | u.profit = v.profit + p[u.level] 86 | u.weight = v.weight + w[u.level] 87 | #take v's list and add u's list 88 | u.items = v.items.copy() 89 | u.items.append(u.level) # adds next item 90 | # print("child that includes the next item: ") 91 | # print("Child 1:") 92 | # print("u.level = ", u.level, "u.profit = ", u.profit, "u.weight = ", u.weight) 93 | # print("u.items = ", u.items) 94 | if u.weight <= W and u.profit > maxprofit: 95 | #update maxprofit 96 | maxprofit = u.profit 97 | # print("\nmaxprofit updated = ", maxprofit) 98 | bestitems = u.items 99 | # print("bestitems = ", bestitems) 100 | u.bound = get_bound(u) 101 | # print("u.bound = ", u.bound) 102 | if u.bound > maxprofit: 103 | pq.insert(u) 104 | # print("Node u1 inserted into pq.") 105 | # print("Priority Queue : ") 106 | # pq.print_pqueue() 107 | #set u to the child that does not include the next item 108 | u2 = Node(u.level, v.profit, v.weight) 109 | nodes_generated+=1 110 | u2.bound = get_bound(u2) 111 | u2.items = v.items.copy() 112 | # print("child that doesn't include the next item: ") 113 | # print("Child 2:") 114 | # print("u2.level = ", u2.level, "u2.profit = ", u2.profit, "u2.weight = ", u2.weight, "u2.bound = ", u2.bound) 115 | # print("u2.items = ", u2.items) 116 | if u2.bound > maxprofit: 117 | pq.insert(u2) 118 | 119 | print("\nEND maxprofit = ", maxprofit, "nodes generated = ", nodes_generated) 120 | print("bestitems = ", bestitems) 121 | 122 | 123 | 124 | 125 | 126 | 127 | --------------------------------------------------------------------------------