Skip to content

Commit 53dd3d2

Browse files
authored
Add files via upload
1 parent 1cd77db commit 53dd3d2

File tree

2 files changed

+206
-0
lines changed

2 files changed

+206
-0
lines changed

knapsack multiple choice.jl

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
2+
# coding: utf-8
3+
4+
# In[1]:
5+
6+
7+
#this is a more advanced knapsack problem
8+
#we have a new variable called groups
9+
#we are only allowed to select at most one item from each group
10+
#please note julia version is a lot more complex than python version
11+
#simply becuz julia starts index at 1 and doesnt allow negative number indexing
12+
#please check the following link for the basic knapsack problem
13+
# https://github.com/je-suis-tm/recursion-and-dynamic-programming/blob/master/knapsack.jl
14+
15+
16+
# In[2]:
17+
18+
19+
#solve multiple choice knapsack via dynamic programming
20+
function knapsack_multichoice(total_weight,values,weights,groups)
21+
22+
#julia starts index at 1 which is why we use length(values)
23+
#create a nested list with size of number of items*weights
24+
array=[[0 for _ in 1:total_weight] for _ in 1:length(values)]
25+
path=[[[] for _ in 1:total_weight] for _ in 1:length(values)]
26+
27+
#now we begin our traversal on all elements in matrix
28+
for i in 1:length(values)
29+
for j in 1:total_weight
30+
31+
#-1 doesnt work as index in julia
32+
#have to find a way to get around
33+
if i==1
34+
if weights[1]<=j
35+
array[1][j]=values[1]
36+
path[1][j]=[1]
37+
end
38+
continue
39+
end
40+
41+
#this is the part to check if adding item i would exceed the current capacity j
42+
#if it does,we go to the previous status
43+
#if not,we shall find out whether adding item i would be the new optimal
44+
if weights[i]<j
45+
46+
#initialize
47+
subset_max=0
48+
target=1
49+
50+
#we only select one item from each group
51+
#we will find the item that maximizes the value in each group
52+
prev_group=groups[i]-1
53+
54+
#get column of the matrix
55+
subset=[row[j-weights[i]] for row in array]
56+
57+
#find the item that maximizes the value in the previous group
58+
for k in 1:length(values)
59+
if groups[k]==prev_group && subset[k]>subset_max
60+
subset_max=subset[k]
61+
target=k
62+
end
63+
end
64+
65+
#dynamic programming
66+
if subset_max+values[i]>array[i-1][j]
67+
array[i][j]=subset_max+values[i]
68+
path[i][j]=[path[target][j-weights[i]];[i]]
69+
elseif subset_max+values[i]==array[i-1][j] && weights[i]<weights[path[i-1][j][end]]
70+
array[i][j]=subset_max+values[i]
71+
path[i][j]=[path[target][j-weights[i]];[i]]
72+
else
73+
array[i][j]=array[i-1][j]
74+
path[i][j]=path[i-1][j]
75+
end
76+
77+
elseif weights[i]==j
78+
79+
#dynamic programming
80+
if values[i]>array[i-1][j]
81+
array[i][j]=values[i]
82+
path[i][j]=[i]
83+
elseif values[i]==array[i-1][j] && weights[i]<weights[path[i-1][j][end]]
84+
array[i][j]=values[i]
85+
path[i][j]=[i]
86+
else
87+
array[i][j]=array[i-1][j]
88+
path[i][j]=path[i-1][j]
89+
end
90+
91+
else
92+
array[i][j]=array[i-1][j]
93+
path[i][j]=path[i-1][j]
94+
end
95+
end
96+
end
97+
return array,path
98+
end
99+
100+
101+
# In[3]:
102+
103+
104+
#a simple test
105+
values=[60,80,100,110,120,150]
106+
weights=[10,15,20,25,30,35]
107+
groups=[0,0,1,1,2,2]
108+
total_weight=50
109+
110+
111+
# In[4]:
112+
113+
114+
array,path=knapsack_multichoice(total_weight,values,
115+
weights,groups)
116+
117+
println(array[length(weights)][total_weight])
118+
println(path[length(weights)][total_weight])
119+
120+

knapsack multiple choice.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
2+
# coding: utf-8
3+
4+
# In[1]:
5+
6+
7+
#this is a more advanced knapsack problem
8+
#we have a new variable called groups
9+
#we are only allowed to select at most one item from each group
10+
#please check the following link for the basic knapsack problem
11+
# https://github.com/je-suis-tm/recursion-and-dynamic-programming/blob/master/knapsack.py
12+
13+
14+
# In[2]:
15+
16+
17+
#solve multiple choice knapsack via dynamic programming
18+
def knapsack_multichoice(total_weight,values,weights,groups):
19+
20+
#python starts index at 0 which is why we use len(values)+1
21+
#create a nested list with size of (number of items+1)*(weights+1)
22+
array=[[0 for _ in range(total_weight+1)] for _ in range(len(values)+1)]
23+
path=[[[] for _ in range(total_weight+1)] for _ in range(len(values)+1)]
24+
25+
#now we begin our traversal on all elements in matrix
26+
#note we would be using i-1 to imply item i
27+
for i in range(1,len(values)+1):
28+
for j in range(1,total_weight+1):
29+
30+
#this is the part to check if adding item i would exceed the current capacity j
31+
#if it does,we go to the previous status
32+
#if not,we shall find out whether adding item i would be the new optimal
33+
if weights[i-1]<=j:
34+
35+
#we only select one item from each group
36+
#we will find the item that maximizes the value in each group
37+
prev_group=groups[i-1]-1
38+
39+
#initialize
40+
subset_max=0
41+
target=0
42+
43+
#get column of the matrix
44+
subset=[row[j-weights[i-1]] for row in array]
45+
46+
#find the item that maximizes the value in the previous group
47+
for k in range(len(values)+1):
48+
if groups[k-1]==prev_group and subset[k]>subset_max:
49+
subset_max=subset[k]
50+
target=k
51+
52+
#dynamic programming
53+
if subset_max+values[i-1]>array[i-1][j]:
54+
array[i][j]=subset_max+values[i-1]
55+
path[i][j]=path[target][j-weights[i-1]]+[i-1]
56+
elif subset_max+values[i-1]==array[i-1][j] and weights[i-1]<weights[path[target][j-weights[i-1]][-1]]:
57+
array[i][j]=subset_max+values[i-1]
58+
path[i][j]=path[target][j-weights[i-1]]+[i-1]
59+
else:
60+
array[i][j]=array[i-1][j]
61+
path[i][j]=path[i-1][j]
62+
else:
63+
array[i][j]=array[i-1][j]
64+
path[i][j]=path[i-1][j]
65+
66+
return array,path
67+
68+
69+
# In[3]:
70+
71+
72+
#a simple test
73+
values=[60,80,100,110,120,150]
74+
weights=[10,15,20,25,30,35]
75+
groups=[0,0,1,1,2,2]
76+
total_weight=50
77+
78+
79+
# In[4]:
80+
81+
82+
array,path=knapsack_multichoice(total_weight,values,weights,groups)
83+
84+
print(array[len(weights)][total_weight])
85+
print(path[len(weights)][total_weight])
86+

0 commit comments

Comments
 (0)