## Aim: find the columns of X that, when summed, give y
## random data set
nc <- 25L; nr <- 5L; howManyCols <- 5L
X <- array(runif(nr*nc), dim = c(nr, nc))
xTRUE <- sample(1L:nc, howManyCols)
Xt <- X[ , xTRUE, drop = FALSE]
y <- rowSums(Xt)
## a random solution x0 ...
makeRandomSol <- function(nc) {
ii <- sample.int(nc, sample.int(nc, 1L))
x0 <- numeric(nc); x0[ii] <- 1L
x0
}
x0 <- makeRandomSol(nc)
## ... but probably not a good one
sum(y - rowSums(X[ , as.logical(x0), drop = FALSE]))
sum(y - rowSums(X[ , xTRUE, drop = FALSE]))
## a neighbourhood function: switch n elements in solution
neighbour <- function(xc, data) {
xn <- xc
p <- sample.int(data$nc, data$n)
xn[p] <- abs(xn[p] - 1L)
if (sum(xn) < 1L) xn <- xc
xn
}
## a greedy neighbourhood function
neighbourG <- function(xc, data) {
of <- function(x)
abs(sum(data$y - rowSums(data$X[,as.logical(x), drop = FALSE])))
xbest <- xc
Fxbest <- of(xbest)
for (i in 1L:data$nc) {
xn <- xc; p <- i
xn[p] <- abs(xn[p] - 1L)
if (sum(xn) > 1L) {
Fxn <- of(xn)
if (Fxn <= Fxbest) {
xbest <- xn; FXbest <- Fxn
}
}
}
xbest
}
## an objective function
OF <- function(xn, data)
abs(sum(data$y - rowSums(data$X[ ,as.logical(xn), drop = FALSE])))
## (1) *greedy search*
## note: this could be done in a simpler fashion. but the
## redundancies/overhead here are small; and the example is to
## show how LSopt can be used for such a search
data <- list(X = X, y = y, nc = nc, nr = nr, n = 1L)
algo <- list(nS = 500L, neighbour = neighbourG, x0 = x0,
printBar = FALSE, printDetail = FALSE)
sol <- LSopt(OF, algo = algo, data = data)
sort(which(as.logical(sol$xbest)))
sort(xTRUE)
sol$OFvalue
par(ylog = TRUE)
plot(sol$Fmat[ ,2L],type = "l", log = "y",
ylim = c(1e-4, max(pretty(sol$Fmat[ ,2L]))),
xlab = "iterations", ylab = "OF value")
## (2) *Local Search*
algo$neighbour <- neighbour
sol <- LSopt(OF, algo = algo, data = data)
sort(which(as.logical(sol$xbest)))
sort(xTRUE)
sol$OFvalue
lines(sol$Fmat[ ,2L], type = "l", lty = 2)
## (3) *Threshold Accepting*
algo$nT <- 10L
algo$nS <- ceiling(algo$nS/algo$nT)
sol2 <- TAopt(OF, algo = algo, data = data)
sort(which(as.logical(sol2$xbest)))
sort(xTRUE)
sol2$OFvalue
lines(cummin(sol2$Fmat[ ,2L]),type = "l", lty = 3)
Run the code above in your browser using DataLab