The Knapsack problem implementation in R
Our own research paper ESG Scores and Price Momentum Are More Than Compatible utilized the Knapsack problem to make the ESG strategies more profitable or Momentum strategies significantly less risky. The implementation of the Knapsack problem was created in R, using slightly modified Simulated annealing optimization algorithm. Recently, we have been asked about our implementation and the code. The code is commented and probably could be implemented more efficiently (in R or in another programming language). For example, R is more efficient with matrices, but the code would not be that “straightforward”. Lastly, the most important tuning parameter is the temperature decrease (the probability of accepting a new solution is falling with the rising number of iterations). Feel free to contact us with any questions or new ideas!
Commented and ready to be copied code:
##### Simulated annealing Knapsack optimization ####
### this parametrization minimizes the value ###
### in the application, pick the vector of values accordingly ###
### for example the inverse of ESG scores ###
#m is vector of weights
#c is vector of values
#M is weight cap
#numbit is number of iterations, 100000 was used in the Knapsack ESG-Momentum
#par is a plotting paramter, if the plotting is enabled, plots and returns each par´s result
#tau is initial temperature
#pt controls the temperature decrease; decrease is set to be linear and pt was set to be 2.5 in the paper
#plotting - logical, TRUE if plotting is enabled, FALSE if disabled
knap.sann<-function(m,c,M,numbit,par,tau,pt,plotting){
#vectors for plotting
weight<-rep(0,numbit/par)
value<-rep(0,numbit/par)
#setting the n
n<-length(m)
x<-rep(0,n)
#solutions
bestval<-0
bestsol<-c(0)
for (i in 1:numbit){
y<-x
#generating random item
p<-sample(1:n,1)
y[p]<-abs(y[p]-1)
#new item is placed into knapsack (or dropped from knapsack) only if it fits into knapsack,
#if it does not fits,
#one item from the knapsack is taken into hand and either chosen item (p) or item in the hand (hand) is dropped
while (t(y)%*%m>M){
hand<-sample(x,1)
y[sample(c(p,hand),1)]<-0
}
#Simulated annealing part; section three in the paper ESG Scores and Price Momentum Are More Than Compatible
if (runif(1) < exp((t(x)%*%c - t(y)%*%c) / (tau / (pt*i)))) {
if(t(y)%*%c>bestval){
bestval<-t(y)%*%c
bestsol<-y
}
x <- y
}
#plotting
if(plotting==TRUE){
if(i %% par ==0){
print(t(x)%*%c)
print(t(x)%*%m)
weight[i/par]<-t(x)%*%m
value[i/par]<-t(x)%*%c
}
}
}
if(plotting==TRUE){
osX<-seq(1:length(weight))
par(mfrow=c(2,1))
plot(osX,weight)
lines(osX,rep(M,length(osX)),col="red")
plot(osX,value)
}
#results
results <- list()
results$first <- bestsol
results$second <- bestval
return(results)
#return(bestsol)
}
Author: Matus Padysak, Senior Analyst, Quantpedia.com
Are you looking for more strategies to read about? Sign up for our newsletter or visit our Blog or Screener.
Do you want to learn more about Quantpedia Premium service? Check how Quantpedia works, our mission and Premium pricing offer.
Do you want to learn more about Quantpedia Pro service? Check its description, watch videos, review reporting capabilities and visit our pricing offer.
Are you looking for historical data or backtesting platforms? Check our list of Algo Trading Discounts.
Or follow us on:
Facebook Group, Facebook Page, Twitter, Linkedin, Medium or Youtube
Share onLinkedInTwitterFacebookRefer to a friend