заполнить матрицу числами в каждой строке, чтобы создать партнера - PullRequest
1 голос
/ 16 января 2020

Я пытаюсь сгенерировать партер поездки, используя матрицу.

    Glastonbury Munich Venice Paris Ibiza Kamar-Taj
 [1,]           1      2      3     4     5         6
 [2,]           1      2      3     4     5         0
 [3,]           1      2      3     4     0         0
 [4,]           1      2      3     0     0         0
 [5,]           1      2      0     0     0         0
 [6,]           3      2      1     4     5         6
 [7,]           0      2      3     4     1         0
 [8,]           0      1      2     0     0         0
 [9,]           5      1      3     2     0         0

каждая строка представляет отдельное путешествие, а число в ячейке представляет порядок, в котором они побывали в каждом месте. Ноль означает, что они не посещали это место.

в настоящее время я создаю это так:

tripMatrix <- list()

tripMatrix[[ 1 ]] <- c(1, 2, 3, 4, 5, 6)
tripMatrix[[ 2 ]] <- c(1, 2, 3, 4, 5, 0)
tripMatrix[[ 3 ]] <- c(1, 2, 3, 4, 0, 0)
tripMatrix[[ 4 ]] <- c(1, 2, 3, 0, 0, 0)
tripMatrix[[ 5 ]] <- c(1, 2, 0, 0, 0, 0)
tripMatrix[[ 6 ]] <- c(3, 2, 1, 4, 5, 6)
tripMatrix[[ 7 ]] <- c(0, 2, 3, 4, 1, 0)
tripMatrix[[ 8 ]] <- c(4, 5, 3, 2, 1, 0)
tripMatrix[[ 8 ]] <- c(0, 1, 2, 0, 0, 0)
tripMatrix[[ 10 ]] <- c(5, 1, 3, 2, 0, 0)

trips <- matrix(unlist(tripMatrix), ncol = 6, byrow = TRUE)

Я могу сделать это только для нескольких строк, но я хотел бы сгенерировать N рядов с различными сочетаниями мест посетил во время поездки.

Пожалуйста, я могу сделать это для N строк, не создавая список поездок вручную?

Ответы [ 4 ]

5 голосов
/ 16 января 2020

Начиная с математического подхода, думая о теоретическом количестве поездок. Например, из 6 мест вы можете выбрать 4 для посещения (т.е. 6C4 = 6 выберите 4), и среди этих 4 мест вы можете посетить их в любом порядке, давая 4! (4 факторных) способа посещения их в разной последовательности. То же самое относится и к другому количеству мест, давая теоретическое число 6! + 6C5 * 5! + 6C4 * 4! + 6C3 * 3! + 6C2 * 2! + 6C1 = 1956 возможных поездок.

Вот вариант, использующий utils::combn и RcppAlgos::permuteGeneral для генерации всех 1956 возможностей:

nc <- 6L
l <- lapply(1L:nc, function(n) combn(1L:nc, n, 
    function(x) {
        if (length(x) > 1L) {
            p <- RcppAlgos::permuteGeneral(x, length(x))
            a <- matrix(0L, nrow=nrow(p), ncol=nc)
            a[cbind(c(row(p)), c(p))] <- col(p)
        } else {
            a <- integer(nc)
            a[x] <- 1L
        }
        a
    }, simplify=FALSE))

m <- do.call(rbind, unlist(l, recursive=FALSE))

head(m, 20):

      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    0    0    0    0    0
 [2,]    0    1    0    0    0    0
 [3,]    0    0    1    0    0    0
 [4,]    0    0    0    1    0    0
 [5,]    0    0    0    0    1    0
 [6,]    0    0    0    0    0    1
 [7,]    1    2    0    0    0    0
 [8,]    2    1    0    0    0    0
 [9,]    1    0    2    0    0    0
[10,]    2    0    1    0    0    0
[11,]    1    0    0    2    0    0
[12,]    2    0    0    1    0    0
[13,]    1    0    0    0    2    0
[14,]    2    0    0    0    1    0
[15,]    1    0    0    0    0    2
[16,]    2    0    0    0    0    1
[17,]    0    1    2    0    0    0
[18,]    0    2    1    0    0    0
[19,]    0    1    0    2    0    0
[20,]    0    2    0    1    0    0
0 голосов
/ 16 января 2020

Вот базовое решение R без использования каких-либо дополнительных пакетов:

# define your own permutation function
perm <- function(x) {
  if (length(x)==1) return(t(x))
  subset(r <- do.call(expand.grid,replicate(length(x),x,simplify = F)), colSums(apply(r, 1, duplicated))==0)
}

# define function that give all permutations with given number of posistions
f <- function(x,vl) {
  p <- perm(x)
  unname(t(apply(p, 1, function(q) replace(rep(0,vl),q,seq_along(q)))))
}

# generate the desired output
v = 1:6
res <- do.call(rbind,
               Map(f, 
                   vl = length(v),
                   unlist(sapply(seq_along(v), function(k) combn(v,k,simplify = F)),recursive = F)))

такое, что

> head(res,25)
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    0    0    0    0    0
 [2,]    0    1    0    0    0    0
 [3,]    0    0    1    0    0    0
 [4,]    0    0    0    1    0    0
 [5,]    0    0    0    0    1    0
 [6,]    0    0    0    0    0    1
 [7,]    2    1    0    0    0    0
 [8,]    1    2    0    0    0    0
 [9,]    2    0    1    0    0    0
[10,]    1    0    2    0    0    0
[11,]    2    0    0    1    0    0
[12,]    1    0    0    2    0    0
[13,]    2    0    0    0    1    0
[14,]    1    0    0    0    2    0
[15,]    2    0    0    0    0    1
[16,]    1    0    0    0    0    2
[17,]    0    2    1    0    0    0
[18,]    0    1    2    0    0    0
[19,]    0    2    0    1    0    0
[20,]    0    1    0    2    0    0
[21,]    0    2    0    0    1    0
[22,]    0    1    0    0    2    0
[23,]    0    2    0    0    0    1
[24,]    0    1    0    0    0    2
[25,]    0    0    2    1    0    0
0 голосов
/ 16 января 2020

Вы можете использовать грубую силу, чтобы сделать это, и в этом случае это полностью выполнимо. Я думаю, что мой яснее, чем предыдущие ответы:

vector<-c(1:6, rep(0,6))  # This is what you need as combinations
Data<-data.frame()        # Initilizing Dataframe
i<-1                      # Just to check total iterations
N<-1956                   # Number of unique combinations to get

while(nrow(Data)<=N){
  i<- i+1
  Data<- rbind(Data,sample(vector, 6, replace = F))
  Data<-Data[!duplicated(Data),]
}
0 голосов
/ 16 января 2020

Вы можете использовать sample и replicate, например:

N <- 10
unique_trip_locations <- 6

t(replicate(N, sample(0:unique_trip_locations, unique_trip_locations)))


#      [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]    2    3    1    5    0    6
# [2,]    5    3    6    2    0    1
# [3,]    2    4    1    3    0    5
# [4,]    1    6    5    3    0    2
# [5,]    6    3    1    4    2    0
# [6,]    1    2    0    6    5    4
# [7,]    5    1    3    0    4    6
# [8,]    0    4    6    2    3    1
# [9,]    0    5    1    3    2    6
#[10,]    5    6    0    1    3    2

Однако, у этого есть одно ограничение, что 0 может появляться максимум только один раз, как и все другие числа.

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