r - 如何将所有可能的字段划分到R中的矩阵中
问题描述
我有这个领域:
我想要的是获得该领域的所有潜在描述。但是有一个限制,划界必须只包括相邻的宿舍。这意味着我们无法划分第 1 至第 4 季度和第 2 至第 3 季度。潜在划分的数量由以下公式给出:
|N| = $$(\sum_{i=1}^{Width-MinWidth+1} i)(\sum_{i=1}^{Length-MinLength+1} i)$$ ,
其中 Width 等于字段的宽度,Length 等于字段的长度(在这种情况下,两者都是 2),MinWidth 等于区域的最小宽度,MinLength 等于区域的最小长度(在这种情况下,它们可以是 1或 2)。
因此,如果 MinWidth = 1 且 MinLength = 1,在本例中为 |N| = 9。
我想在相应的矩阵中有这个字段的矩形区域。此示例的相应矩阵必须如下所示:
[,1] [,2] [,3] [,4]
[1,] 1 0 0 0
[2,] 0 1 0 0
[3,] 0 0 1 0
[4,] 0 0 0 1
[5,] 1 1 0 0
[6,] 0 0 1 1
[7,] 1 0 1 0
[8,] 0 1 0 1
[9,] 1 1 1 1
该矩阵的解释是,第一次划分仅包括第一季度(以及 2,3,4 一起),第二次划分仅包括第二季度(以及 1,3,4 一起),...,第五分度包括第一和第二季度(和 3,4 一起),所以它继续。3x3 字段的矩阵将是 36x9 矩阵,类似于上面的矩阵。
我已经设法建立了一个与 |N| 交互的循环 次(潜在描绘的数量),代码如下:
z <- 0
for (j in MinWidth:Width) {
for (l in 0:(Width - 1)) {
if ((j + l) <= Width) {
for (i in MinLength:Length) {
for (k in 0:(Length-1)) {
if ((k + i) <= Length) {
z <- z + 1
}
}
}
}
}
}
这个循环的作用是:
它需要四分之一然后检查是否有剩余空间,首先是横向然后纵向,以创建一个区域。j 代表宽度,l 代表剩余可用宽度,i 代表长度,k 代表剩余可用长度。但是我无法为每个循环获得正确的矩阵行。
有什么想法我怎么能在 R 中做到这一点?
解决方案
这是一个有点复杂的解决方案(当然可以优化),因为它确实返回了只有基数 R 的矩阵。只需输入 mat(l,w) 其中 l 和 w 描述字段的长度和宽度:
library(nnls)
expand <- function(x) {
out = x
index = which(is.na(x))
for(i in 1:length(index)) {
y = x[(index[i]+1):length(x)]
add = length(x)-length(y)
out = rbind(out,c(y,rep(NA,add)))
}
return(out)
}
check_split <- function(M) {
check = c()
for(i in 1:nrow(M)) {
Y = ifelse(M[i,] == 1,0,1)
mod = round(coef(nnls(t(M[-i,]),matrix(Y))),10)
mod[is.na(mod)] = 0
check = c(check,all(mod %in% c(1,0)))
}
return(check)
}
mat <- function(l,w,minL,minW) {
print(matrix(1:(l*w),byrow=T,nrow=l))
out = list()
x=c()
for(i in 1:(l*w)) {
if(i%%w == 0){
x = c(x,i,NA)
} else {
x = c(x,i)
}
}
y = expand(x)
for (m in 1:l) {
y = expand(x)[1:m,]
for (n in 0:w) {
for (i in 1:length(x)) {
if(m == 1) {
out = c(out,list(y[i:(i+n)]))
} else {
out = c(out,list(y[,i:min((i+n),ncol(y))]))
}
}
}
}
allCombinations = out[unlist(lapply(out,function(x) !any(is.na(x))))]
allCombinations = lapply(allCombinations,as.matrix,byrow=T)
allCombinations = lapply(allCombinations,function(x) if(ncol(x)==1 & is.null(rownames(x))){t(x)}else{x})
## Account for restrictions
lengths = lapply(allCombinations, nrow)
widths = lapply(allCombinations, ncol)
simple = lapply(allCombinations, function(x) sort(as.vector(x)))[lengths >= minL & widths >= minW]
## Desired matrix
output = do.call(rbind, lapply(simple, function(x) ifelse(1:(l*w) %in% x, 1,0)))
output[check_split(output),]
}
如果有困惑,很乐意回答问题。
推荐阅读
- graphql - 即使我将限制设置为 -1,strapi graphql 限制也只返回 100 个项目
- c# - Postgresql 函数到 C#
- php - Laravel 找出角色中选择了哪些权限
- python - 在 Flyte 中的任务之间传递 blob
- ruby-on-rails - Rails 6 字段必填,但不接受 0 或 Null
- python - ValueError:残差在初始点不是有限的。(Python)
- python-3.x - 根据 Groupby 和单独列中的值在数据框中创建一个新列
- javascript - TypeError:在 mongoDB/mongoose 中将循环结构转换为 JSON
- sql - Oracle:基于循环选择的更新
- r - R:使用 coord_trans 时 y 轴消失