R: Печать ВСЕХ длинных увеличивающихся подпоследовательностей (LIS) - PullRequest
0 голосов
/ 25 января 2019

Учитывая вектор

x <- c(4,5,6,7,8,9,10,11,12,13,15,14,13,12,11,10,9,8,6)

Найти ВСЕ самые длинные растущие подпоследовательности (LIS)

Решение должно выглядеть так:

4,5,6,7,8,9,10,11,12,13,14

4,5,6,7,8,9,10,11,12,13,15

Я мог бы даже сделать синдекс элементов

Я использовал код, заданный JINJING XIE , но он возвращает только одну последовательность

Любая помощь будет оценена

1 Ответ

0 голосов
/ 25 января 2019

Вот (медленная и не очень эффективная) функция, которая будет ее вычислять (использует RcppAlgos)

max_sub_sequences <- function (x) {  
  # x incresing, result is obviously x
  if (all(diff(x) > 0)) return (x)
  N <- length(x)
  n <- N - 1L 
  break_condition <- TRUE
  while (break_condition) {
    # generate all combinations of indices
    combinations <- RcppAlgos::comboGeneral(1:N,n)    
    # get subsequences according to indices
    sub_sequences <- matrix(x[combinations[1:nrow(combinations),]], nrow = nrow(combinations)) ; rm(combinations)
    # check monotony 
    index_subsequence <- vapply(1:nrow(sub_sequences), function (k) any(diff(sub_sequences[k,]) < 1L), logical(1L))
    # keep increasing sequences only
    sub_sequences <- sub_sequences[!index_subsequence,] ; rm(index_subsequence)
    break_condition <- nrow(sub_sequences) == 0L
    n <- n - 1L
  }
  sub_sequences
 }
max_sub_sequences(c(4,5,6,7,8,9,10,11,12,13,15,14,13,12,11,10,9,8,6))    
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
# [1,]    4    5    6    7    8    9   10   11   12    13    15
# [2,]    4    5    6    7    8    9   10   11   12    13    14  

# timing
# Unit: seconds
#                 expr     min       lq     mean   median       uq      max neval
# max_sub_sequences(x) 1.30611 1.462473 1.502727 1.484785 1.522796 1.821037   100

Существуют определенные способы сделать его более эффективным, например, другая логика или записав ее в c++ и используя Rcpp для всей задачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...