Background
Assuming we have a family of matrices M
s of size n
-by-n
, which should meet the following requirements:
- Entries of the matrix are either
0
or1
, i.e., boolean, but diagonal entries are always0
s - The matrix is symmetric, i.e.,
M == t(M)
- There is a constant row (or equivalently, column) sum constraint
p
, such thatall(rowSums(M)==p) == TRUE
Questions
- Is there any potential features from the particular matrix structure, e.g., symmetry, boolean, or somethings else, such that we can take benefits from that to improve the efficiency of searching?
- It seems that the problem can be interpreted as a graph theory way. For example, the matrix is an adjacent matrix of a graph that consists of
n
vertices with both indegrees and outdegrees being equal top
. This can be done bysample_degseq
, but we may have to find all of its isomorphic mappings. How can we do that if we useigraph
approaches?
My code so far looks like below, but it is slow when we have larger n
or p
(and also I am not sure if some of matrices are missed during the enumeration).
f <- function(n, p) {
# helper function to check if requirement holds
checker <- function(M, p, i = nrow(M) - 1) {
rs <- rowSums(M)
if ((i == nrow(M) - 1)) {
return(all(rs == p))
} else {
return(all(rs[1:i] == p) && all(rs[-(1:i)] <= p))
}
}
# start from all-0's matrix
lst <- list(matrix(0, n, n))
for (i in 1:(n - 1)) {
js <- (i + 1):n
r <- list()
for (mat in lst) {
k <- p - sum(mat[i, ])
if (k == 0) {
if (checker(mat, p, i)) {
r <- c(r, list(mat))
}
}
if (k > 0 && length(js) >= k) {
idx <- combn(length(js), k, \(v) js[v], simplify = FALSE)
for (u in idx) {
mm <- mat
mm[i, u] <- 1
mm[u, i] <- 1
if (checker(mm, p, i)) {
r <- c(r, list(mm))
}
}
}
}
lst <- r
}
lst
}
Examples
- For
n <- 4
andp <- 2
, we can find 3 matrices
[[1]]
[,1] [,2] [,3] [,4]
[1,] 0 1 1 0
[2,] 1 0 0 1
[3,] 1 0 0 1
[4,] 0 1 1 0
[[2]]
[,1] [,2] [,3] [,4]
[1,] 0 1 0 1
[2,] 1 0 1 0
[3,] 0 1 0 1
[4,] 1 0 1 0
[[3]]
[,1] [,2] [,3] [,4]
[1,] 0 0 1 1
[2,] 0 0 1 1
[3,] 1 1 0 0
[4,] 1 1 0 0
- For
n <- 3
andp <- 2
, we can find only 1 matrix
[[1]]
[,1] [,2] [,3]
[1,] 0 1 1
[2,] 1 0 1
[3,] 1 1 0