1

I am a beginner in R. I am working on linear programming using R studio's Cplex to solve a model. One of the constraint in my model is Xl(i,j,t) <= D(i,j,t). I am able to do this with nested for loop with a small dimension (16X16X6). But I want to run my model a lot bigger model, more like 2500X2500X60. I need to save memory and run it faster than the nested for loop. I thought about using apply but I don't know how to make it work. Any help would be greatly appreciated!

location <-16
horizon <-6
Amat <- NULL
Xe_null <- array(0, dim = c(locations, locations, horizon))
Xl_null <- array(0, dim = c(locations, locations, horizon))
Xl      <- array(0, dim = c(locations, locations, horizon))
Xl <- Xl_null
for (t in 1:horizon) {
  for (j in 1:locations) {
    for (i in 1:locations) {
      Xl[i,j,t] <- 1
      Amat <- rbind(Amat, c(as.vector(Xe_null), as.vector(Xl)))
      Xl <- Xl_null 
 } } }
dim(Amat) # 1536 3072

Here is another constraint.

R       <- array(, dim=c(locations, horizon, horizon))
R_null  <- array(, dim=c(locations, horizon, horizon))
R <- R_null
Xe <- Xe_null
Xl <- Xl_null
#
for (t in 1:(horizon-1)) {
  for (tp in (t+1):horizon) {
    for (j in 1:locations)     {
      for (i in 1:locations)      {
        if ((tp-t) ==Travel_time[i,j]) 
        {
          Xe[i,j,t]=1
          Xl[i,j,t]=1
        } 
      }
      R[j,tp,t] = 1
      R[j,tp,t+1] = -1
      Amat <- rbind(Amat, c(as.vector(Xe), as.vector(Xl),as.vector(R)))
      }
  }
}

I try to do this:

Xl = function(ii,jj,tt){1}
t =c(1:horizon)
i =c(1:locations)
j =c(1:locations)
output_Xl = apply(expand.grid(i,j,t),1,function(x,y,h) Xl(x[1],x[2],x[3]))
Xl_new <- array(output_Xl, dim = c(locations, locations, horizon))
Amat <- rbind(Amat, c(as.vector(Xe_null), as.vector(Xl_new)))
dim(Amat) # 1 3072
2
  • Is Xl_null and Xe_null the same object or is Xe_null is the original data? Commented Dec 7, 2017 at 14:53
  • Yes, Xl_null and Xe_null are empty with zero. Commented Dec 7, 2017 at 14:56

2 Answers 2

2

You can get the same output with

T <- horizon*locations*locations
Bmat <- cbind(matrix(0, nrow=T, ncol=T), diag(1, nrow=T, ncol=T))
identical(Amat, Bmat)
# TRUE
Sign up to request clarification or add additional context in comments.

Comments

2

I think what you need is to make a vectorized function giving the same output (see ?Vectorize). Below code is five hundred times as fast as yours.
At your real problems, maybe you need to use <<- instead of <- (see ?"<<-")

my_func <- function(a, b, c){
  Xl[a, b, c] <- 1
  c(as.vector(Xe_null), as.vector(Xl))
}

vectorized_my_func <- Vectorize(my_func, c("a", "b", "c"))

arg_df <- expand.grid(1:locations, 1:locations, 1:horizon)
res <- vectorized_my_func(arg_df[,1], arg_df[,2], arg_df[,3])

identical(Amat, t(res))    # TRUE

# your code
##   user  system elapsed 
## 77.538  18.293  97.056 

# my code
##   user  system elapsed 
###  0.137   0.051   0.189 

2 Comments

Thank you for the help and the suggestion of editing my post. Very helpful! Thanks :)
Hi, I just have a follow-up question. When I switch the locations <- 2500, horizon <- 60. I ran out of memory. Should I look into Sparse Matrix? Or do you have better suggestions?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.