t-student
t-student

Reputation: 434

Enumeration of distinct events in R

I am searching for an general approach to enumerate the sequence associated with the following problem and deposit the results in a 3 dimensional matrix in R.

I think there must be a combinatorial solution but I have been unable to find one. Hopefully, what is detailed below will sufficiently characterize the problem. Any help welcomed.

Given that there are n periods and c distinct areas in which the occurrence of an event e must occur exactly once in each area, what is the enumeration of possible sequences?

For example, if there are 3 time periods {1,2,3} and 2 areas {a,b}, manually enumerating the solutions gives:

Period 1    2    3
Area   a b  a b  a b
Sol 1  e e  - -  - -   ; ie event occurs in both areas at time 1, nothing happens at time 2 and 3
Sol 2  - -  e e  - -   ; event occurs in both areas at time 2 etc
Sol 3  - -  - -  e e
Sol 4  e -  - e  - -
Sol 5  e -  - -  - e
Sol 6  - e  e -  - -
Sol 7  - e  - -  e -
Sol 8  - -  e -  - e
Sol 9  - -  - e  e -

Regardless of the number of areas and number of time steps, what I do know is that the number of solutions will always be n^c. For this case that is 3 ways for event to occur in 'a' times 3 ways for event to occur in 'b', 3 x 3 = 9 distinct sequences. As said, I wish to implement a generalized solution for any number of periods and any number of areas and store the result in a matrix indexed by [time][area][sequence]. Thanks!

Upvotes: 2

Views: 490

Answers (2)

t-student
t-student

Reputation: 434

Many thanks. I believe the following is working correctly.

# Solution:
numperiods <- 4
numevents <- 2
numseqs <- numperiods^numevents

gridparam <- rep(list(seq(numperiods)),numevents)
g <- as.matrix(expand.grid(gridparam))
print(g)

m <- t(apply(g, 1, 
         function(z) {
            x <- rep(0, numperiods*numevents) 
            for (i in 1:numseqs) 
            {
              x[numevents * z[i] - (numevents-i)] <- 1
            }
            x
         }))
print(m)

result <- array(m,c(numseqs,numevents,numperiods))
colnames(result) <- outer("Event",1:numevents, paste)
rownames(result) <- outer("Seq", 1:numseqs, paste)
# Time period is third dim
print(result)

Upvotes: 1

sieste
sieste

Reputation: 9057

So there are two events, and each event can happen in one of three periods. You can enumerate all possible combinations of periods in which the 2 events happen using expand.grid:

g <- as.matrix(expand.grid( seq(3), seq(3) ))
print(g)
      Var1 Var2
 [1,]    1    1
 [2,]    2    1
 [3,]    3    1    
 [4,]    1    2
 [5,]    2    2
 [6,]    3    2
 [7,]    1    3
 [8,]    2    3
 [9,]    3    3

Now loop over the rows of g and return vectors which have a 1 ("event") at the correct indices:

m <- t(apply(g, 1, 
             function(z) {
               x <- rep(0, 6)
               x[2 * z[1] - 1] <- 1
               x[2 * z[2]] <- 1
               x
             }))
print(m)
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    1    0    0    0    0
 [2,]    0    1    1    0    0    0
 [3,]    0    1    0    0    1    0
 [4,]    1    0    0    1    0    0
 [5,]    0    0    1    1    0    0
 [6,]    0    0    0    1    1    0
 [7,]    1    0    0    0    0    1
 [8,]    0    0    1    0    0    1
 [9,]    0    0    0    0    1    1

This is the matrix you are looking for in binary form.

If you have more than 2 events, add another seq(3) inside expand.grid, and adjust the function inside apply. Likewise, if there are more than 3 periods, change seq(3) to seq(number.of.periods).

Upvotes: 0

Related Questions