|
| 1 | + |
| 2 | +# coding: utf-8 |
| 3 | + |
| 4 | +# In[1]: |
| 5 | + |
| 6 | + |
| 7 | +#this has nothing to do with recursion algorithm |
| 8 | +#it happened to be in the recursion chapter in my book |
| 9 | +#so i kept it under recursion |
| 10 | +#its about dynamic programming |
| 11 | +#its kinda tricky to understand |
| 12 | +#if you are familiar with convex optimization or lagrangian |
| 13 | +#its better to use em instead of this |
| 14 | + |
| 15 | + |
| 16 | +#knapsack problem is to maximize the value |
| 17 | +#while having a weight constraint |
| 18 | +#each value has a different weight |
| 19 | +#the knapsack has a maximum capacity which is the constraint |
| 20 | + |
| 21 | + |
| 22 | +#to solve the problem,we have to use recursive thinking |
| 23 | +#lets create a list from 1 to the maximum capacity |
| 24 | +#for each capacity in the list |
| 25 | +#we try to reach the optimal allocation of weight at the given capacity |
| 26 | +#say we have c as the maximum capacity |
| 27 | +#we remove the last item i |
| 28 | +#we get weight capacity-weight[i] |
| 29 | +#we wanna make sure our allocation at capacity-weight[i] is still the optimal |
| 30 | +#by optimal,we mean for the same weight we can achieve the highest value |
| 31 | +#if capacity-weight[i] is not the optimal |
| 32 | +#we can find another combo with the same weight but higher value |
| 33 | +#we add the item i back into the knapsack then |
| 34 | +#the new total value we get would be larger than the previous so-called optimal |
| 35 | +#it will contradict the definition of optimal |
| 36 | +#hence,for each capacity,we keep removing items |
| 37 | +#until we reach base case 0,and it always stays the optimal at the given capacity |
| 38 | + |
| 39 | + |
| 40 | +#to get the optimal status |
| 41 | +#we shall do a traversal on all items |
| 42 | +#we create a matrix with (number of items) * (maximum capacity) |
| 43 | +#for each capacity level,we try to add a new item |
| 44 | +#if adding new item causes the overall weight larger than the current capacity level |
| 45 | +#the knapsack reverts to the previous status without item i which is matrix[i-1][j] |
| 46 | +#if adding new item doesnt cause the overall weight bigger than the current capacity level |
| 47 | +#we try to see whether adding item i would be the new optimal case |
| 48 | +#so we compare the previous status with the status after adding item i |
| 49 | +#the status after adding item i shall be matrix[i-1][j-weight[i-1]]+value[i-1] |
| 50 | +#we use j-weight[i-1] cuz adding item i would reduce the capacity we have |
| 51 | +#we have to use the current constraint level j to minus item i weight |
| 52 | + |
| 53 | + |
| 54 | +# In[2]: |
| 55 | + |
| 56 | + |
| 57 | +function knapsack(value,weight,capacity) |
| 58 | + |
| 59 | + #in this section,we create a nested list with size of (number of items+1)*(capacity+1) |
| 60 | + matrix=[[0 for _ in 1:(capacity+1)] for _ in 1:(length(value)+1)] |
| 61 | + |
| 62 | + #now we begin our traversal on all elements in matrix |
| 63 | + #i starts from 2 cuz we would be using i-1 to imply item i |
| 64 | + for i in 2:(length(value)+1) |
| 65 | + |
| 66 | + for j in 2:(capacity+1) |
| 67 | + |
| 68 | + #this is the part to check if adding item i-1 would exceed the current capacity j |
| 69 | + #if it does,we go back to the previous status |
| 70 | + #if not,we shall find out whether adding item i-1 would be the new optimal |
| 71 | + if weight[i-1]>j |
| 72 | + |
| 73 | + matrix[i][j]=matrix[i-1][j] |
| 74 | + |
| 75 | + else |
| 76 | + |
| 77 | + #julia index starts from 1 |
| 78 | + #which is a pain in the ass |
| 79 | + #when current capacity==the new item s weight |
| 80 | + #it creates an issue |
| 81 | + if j==weight[i-1] |
| 82 | + |
| 83 | + ind=1 |
| 84 | + |
| 85 | + else |
| 86 | + |
| 87 | + ind=j-weight[i-1] |
| 88 | + |
| 89 | + end |
| 90 | + |
| 91 | + #we use max funcion to see if adding item i-1 would be the new optimal |
| 92 | + matrix[i][j]=max(matrix[i-1][j], |
| 93 | + matrix[i-1][ind]+value[i-1]) |
| 94 | + |
| 95 | + end |
| 96 | + |
| 97 | + end |
| 98 | + |
| 99 | + end |
| 100 | + |
| 101 | + return matrix[length(value)+1][capacity+1] |
| 102 | + |
| 103 | +end |
| 104 | + |
| 105 | + |
| 106 | +# In[3]: |
| 107 | + |
| 108 | + |
| 109 | +println(knapsack([0,50,60,60,120],[0,10,15,20,40],50)) |
| 110 | + |
0 commit comments