我正在嘗試編寫一個R代碼以返回矩陣中最大的連續數字對。連續的對可以是水平的,垂直的和兩個對角線。R:返回矩陣中最大的連續數字對
例如 如果我有矩陣:
ma = array(c(8,4,3,1,7,5,9,15,6,10,16,11,2,14,12,13), dim = c(4,4))
最高連續對爲(1)的水平:16和12; (2)垂直:16和11(3)對角線():16和13;和(4)對角線(/):16和15.
我如何在R中做到這一點?
我正在嘗試編寫一個R代碼以返回矩陣中最大的連續數字對。連續的對可以是水平的,垂直的和兩個對角線。R:返回矩陣中最大的連續數字對
例如 如果我有矩陣:
ma = array(c(8,4,3,1,7,5,9,15,6,10,16,11,2,14,12,13), dim = c(4,4))
最高連續對爲(1)的水平:16和12; (2)垂直:16和11(3)對角線():16和13;和(4)對角線(/):16和15.
我如何在R中做到這一點?
這是一個使用矩陣算法的解決方案,它將比行和列上的嵌套循環更有效,其中多,尤其是在大型矩陣上。
directionalSums <- function(x){
stopifnot(is.matrix(x))
# padding functions to allow matrix addition
padL <- function(x) cbind(-Inf,x)
padR <- function(x) cbind(x,-Inf)
padU <- function(x) rbind(-Inf,x)
padD <- function(x) rbind(x,-Inf)
# these padding functions are just for readability
padLU <- function(x) padL(padU(x))
padLD <- function(x) padL(padD(x))
padRU <- function(x) padR(padU(x))
padRD <- function(x) padR(padD(x))
m <- nrow(x)
n <- ncol(x)
sumR <- padR((padL(x) + padR(x))[1:m,2:n])
sumD <- padD((padU(x) + padD(x))[2:m,1:n])
sumRD <- padRD((padLU(x) + padRD(x))[2:m,2:n])
sumRU <- padRU((padRU(x) + padLD(x))[2:m,2:n])
list(`right`=sumR,
`down`=sumD,
`right and down`=sumRD,
`right and up`=sumRU)
}
讓我們試試吧。
(sumList <- directionalSums(ma))
maxLocList <- lapply(sumList, function(x) which(x==max(x), arr.ind=TRUE))
for (i in 1:length(maxLocList)){
nameD <- names(maxLocList)[i]
startCell <- maxLocList[[i]]
maxSum <- sumList[[i]][startCell]
x1 <- ma[startCell]
x2 <- maxSum - x1
writeLines(paste0('The max-sum consec. pair going ',
nameD, ' starts at [',
paste(startCell, collapse=', '),
'], with sum ', maxSum,
' and components ', x1, ' and ',x2)
)
}
返回:
$right
[,1] [,2] [,3] [,4]
[1,] 15 13 8 -Inf
[2,] 9 15 24 -Inf
[3,] 12 25 28 -Inf
[4,] 16 26 24 -Inf
$down
[,1] [,2] [,3] [,4]
[1,] 12 12 16 16
[2,] 7 14 26 26
[3,] 4 24 27 25
[4,] -Inf -Inf -Inf -Inf
$`right and down`
[,1] [,2] [,3] [,4]
[1,] 13 17 20 -Inf
[2,] 13 21 22 -Inf
[3,] 18 20 29 -Inf
[4,] -Inf -Inf -Inf -Inf
$`right and up`
[,1] [,2] [,3] [,4]
[1,] -Inf -Inf -Inf -Inf
[2,] 11 11 12 -Inf
[3,] 8 19 30 -Inf
[4,] 10 31 23 -Inf
The max-sum consec. pair going right starts at [3, 3], with sum 28 and components 16 and 12
The max-sum consec. pair going down starts at [3, 3], with sum 27 and components 16 and 11
The max-sum consec. pair going right and down starts at [3, 3], with sum 29 and components 16 and 13
The max-sum consec. pair going right and up starts at [4, 2], with sum 31 and components 15 and 16
這是一種使用簡單(但很長)的代碼來完成它的方法。
既然你正在尋找連續數最大的一對,你應該首先創建一個函數,它需要一個單元格並且找到它所有的連續和。
consec <- function(ma,y,x){
return(
c(if(x<ncol(ma)) ma[y,x] + ma[y,x+1],
if(x>1) ma[y,x] + ma[y,x-1],
if(y<nrow(ma)) ma[y,x] + ma[y+1,x],
if(y>1) ma[y,x] + ma[y-1,x],
if(x<ncol(ma) & y<nrow(ma)) ma[y,x] + ma[y+1,x+1],
if(x>1 & y<nrow(ma)) ma[y,x] + ma[y+1,x-1],
if(x<ncol(ma) & y>1) ma[y,x] + ma[y-1,x+1],
if(x>1 & y>1) ma[y,x] + ma[y-1,x-1])
)
}
此功能(if
語句)確保我們不要去出界,因爲在邊境細胞將有小於8樓的鄰居,形成對連續帶的左半邊。然後右半部分獲得連續對的總和並將其添加到列表中。
現在,如果您使用consec(ma, 3, 2)
,它會爲您提供ma[3,2]
的連續總和向量。
接下來,我們要填充每個單元格的最高連續總和的第二個矩陣。您可以使用以下代碼創建具有正確尺寸的空白矩陣。
ma2 <- matrix(0, nrow = nrow(ma), ncol = ncol(ma))
現在用循環和前面創建的consec
函數填充它。
for(i in 1:nrow(ma)){
for(j in 1:ncol(ma)){
ma2[i,j] <- max(consec(ma,i,j))
}
}
現在,我們有我們連續總和的矩陣,我們可以找到它的最大金額,以及它的座標將對應的地方,我們要在原有的矩陣看。
ma.max <- which(ma2 == max(ma2), arr.ind = TRUE)
現在,如果僅存在一個對數字它是最大值,那麼ma.max
將有兩條線(在同一對的兩個置換)。您可以使用:
ma[ma.max[1,1], ma.max[1,2]]; ma[ma.max[2,1], ma.max[2,2]]
要顯示它們。在這種情況下,我們得到15
和16
,所以它的工作。
如果您有更多的最大值,那麼在上面的代碼中增加數字以獲得下一對(3和4),依此類推。你甚至可以調整consec
函數,例如,如果你不想要對角線連續,然後刪除列表的最後四行。
單曲< - 毫安[1:3,] +毫安[2:4,];其中(s == max(s),arr.ind = TRUE)'獲得行對中第一對的索引;它的對將直接在它下面。對於列,您可以翻轉逗號。對角線將會有更多的工作。 – alistaire
對角線應該是s < - ma [1:3,1:3] + ma [2:4,2:4]; (s == max(s),arr.ind = TRUE)'不是? – BonStats
你正在尋找最大的連續配對?否則,你如何比較對? – C8H10N4O2