R で解決しようとしている奇妙な問題があります
。x と y の 2 つのベクトルがあり、各ベクトル内のすべての要素が一意であり、ベクトルの長さが同じで、ベクトル 2 がベクトルの順列であるとします。 1:
x <- LETTERS[c(1,2,3,4,5,6,7,8,9,10)]
y <- LETTERS[c(5,8,7,9,6,10,1,3,2,4)]
最初と最後の要素が定義された特別なタイプの順列として「チェーン」を定義しましょう。
たとえば、mayt be の順列は、mayt "A" "B" "C" "D"
be"C" "B" "D" "A"
の「チェーン」です。"A" "B" "C" "D"
"A" "C" "B" "D"
私の目標は、x と y に共通するすべての「チェーン」を特定することです。たとえば、x と y には共通の長さ 4 のチェーンがあります。
> x[1:4]
[1] "A" "B" "C" "D"
> y[7:10]
[1] "A" "C" "B" "D"
(チェーンは A、B、C、および D であり、A で始まり D で終わる任意の順序)
共通の長さ 6 のチェーン:
> x[5:10]
[1] "E" "F" "G" "H" "I" "J"
> y[1:6]
[1] "E" "H" "G" "I" "F" "J"
(チェーンは、E、F、G、H、I、および J であり、E で始まり J で終わります)
特定の長さのサブチェーンを識別するために、次の関数を作成しました。
subChains <- function(x, y, Len){
start.x <- rep(NA, length(x))
start.y <- rep(NA, length(y))
for (i in 1:(length(x) - Len + 1)) {
for (j in 1:(length(y) - Len + 1)) {
canidate.x <- x[i:(i+Len-1)]
canidate.y <- y[j:(j+Len-1)]
if (
canidate.x[1]==canidate.y[1] &
canidate.x[Len]==canidate.y[Len] &
all(canidate.x %in% canidate.y) &
all(canidate.y %in% canidate.x)
){
start.x[i] <- i
start.y[i] <- j
}
}
}
return(na.omit(data.frame(start.x, start.y, Len)))
}
次のように使用されます。
> subChains(x, y, 4)
start.x start.y Len
1 1 7 4
また、次の関数を使用して、2 つのベクトルに共通するすべてのチェーンを見つけることができます。
allSubchains <- function(x, y, Lens){
do.call(rbind, lapply(Lens, function(l) subChains(x, y, l)))
}
次のように使用されます。
allSubchains(x, y, Lens=1:10)
start.x start.y Len
1 1 7 1
2 2 9 1
3 3 8 1
4 4 10 1
5 5 1 1
6 6 5 1
7 7 3 1
8 8 2 1
9 9 4 1
10 10 6 1
11 1 7 4
51 5 1 6
もちろん、どちらの関数も非常に遅いです。はるかに大きな問題で妥当な時間内に実行できるように、それらを改善できますか? 例えば
n <- 100000
a <- 1:n
b <- sample(a, n)
allSubchains(a, b, Lens=50:100)