#Your predict function should create this files at the same time
#that it creates the submission. 
#File definition:
# - First column with the row_id
# - Next three columns with the predicted #places (Place1,Place2,Place3), in order
# - Last three columns with the probability assigned to each place (ProbPlace1,ProbPlace2,ProbPlace3). 
createDummyProbFiles<-function()
{
  modelprobs1<-data.frame(
    row_id=c(0,1),
    Place1=c('3831655216','2465239230'),
    Place2=c('8017323210','2411939657'),
    Place3=c('6131996960','9801651394'),
    ProbPlace1=c(0.22,0.35),ProbPlace2=c(0.17,0.08),ProbPlace3=c(0.1,0.08))
  
  modelprobs2<-data.frame(
    row_id=c(0,1),
    Place1=c('6131996960','2465239230'),
    Place2=c('8017323210','9801651394'),
    Place3=c('4393146716','5053057227'),
    ProbPlace1=c(0.16,0.155),ProbPlace2=c(0.14,0.12),ProbPlace3=c(0.095,0.075))
  
  saveRDS(modelprobs1,file = 'Model1DummyProbs.rds')
  saveRDS(modelprobs2,file = 'Model2DummyProbs.rds')
}

#Ensemble function
modelEnsemble<-function()
{
  nCores<-2 #Configure the number of cores available

  #Load libraries
  library(doMC)
  library(foreach)
  library(itertools)
  
  registerDoMC(cores = nCores) 
  
  #Configure files with classes and probs. The format is specified in the function #createDummyProbFiles
  #We can have as much files as we want
  probfiles<-list("Model1DummyProbs.rds","Model2DummyProbs.rds")
  #Weight of each model. More weight means that the predictions of the model will have priority when
  #appearing in the final submission file. We can use the model LB score.
  probfiles_weights<-c(0.58,0.56)
  
  #Load files in parallel as they can be quite heavy
  probs<-foreach (i=1:length(probfiles),.combine="cbind")%dopar%
  {
    p<-readRDS(probfiles[[i]])
    row.names(p)<-p$row_id
    p[,c('Place1','Place2','Place3','ProbPlace1','ProbPlace2','ProbPlace3')]
  }

  probs$row_id<-row.names(probs)

  #Split a few rows to each core
  preds<-foreach (s=isplitRows(probs, chunks=nCores),.noexport = c("probs"),  .combine = 'rbind') %dopar%
  {
    t(apply(s,1,function(x) {
      nensembles<-(length(x)-1)/6
      #Subset places and probs
      places<-x[c(seq(from=1,to = nensembles*6,by=6),seq(from=2,to = nensembles*6,by=6),seq(from=3,to = nensembles*6,by=6))]
      pplaces<-as.numeric(x[c(seq(from=4,to = nensembles*6,by=6),seq(from=5,to = nensembles*6,by=6),seq(from=6,to = nensembles*6,by=6))])
      
      #Apply model weight
      pplaces<-pplaces*rep(probfiles_weights,each=3)
      
      #Order places predicted by each model by probability
      places<-places[order(pplaces,decreasing = TRUE)]
      
      #Erase duplicates. This step is necessary as we don't want duplicates in the three final predicted places
      places<-places[!duplicated(places)]
      
      c(as.integer(x[6*nensembles+1]),places[1:3])
    }))
  }

  #Save the data in the format needed for submission
  preds<-data.frame(row_id=preds[,1],place_id=paste(preds[,2],preds[,3],preds[,4]))
  options(scipen=10)
  write.table(preds,row.names = FALSE, sep = ',', file="submission.csv", quote = FALSE)
}


createDummyProbFiles()
modelEnsemble()
