Reputation: 434
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
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
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