2012-11-21 4 views
2

J'ai le problème suivant. Dire que j'ai un vecteur:Recherche de vecteurs Algorithme

v = [1,2,3,4,5,1,2,3,4,...] 

Je veux séquentiellement les points d'échantillonnage à partir du vecteur, qui ont une différence de maginute absolue supérieure à un seuil d'un point déjà échantillonné. Donc disons que mon seuil est 2.

Je commence à l'index 1, et échantillonne le premier point 1. Alors ma condition est rencontrée à v [3], et j'échantillon 3 (depuis 3-1> = 2). Puis 3, le nouveau point échantillonné devient la référence, que je vérifie. Le prochain point échantillonné est 5 qui est v [5] (5-3> = 2). Alors le point suivant est 1 qui est v [6] (abs (1-5)> = 2). Malheureusement, mon code dans R prend trop de temps. Fondamentalement, je scanne le tableau à plusieurs reprises et à la recherche de correspondances. Je pense que cette approche est naïve cependant. J'ai le sentiment que je peux accomplir cette tâche en un seul passage à travers le tableau. Je ne sais pas comment. Toute aide appréciée. Je suppose que le problème que je rencontre est que l'emplacement du point d'échantillon suivant peut être n'importe où dans le tableau, et j'ai besoin de balayer le tableau du point courant jusqu'à la fin pour le trouver.

Merci.

Répondre

12

Je ne vois pas une façon dont cela peut se faire sans une boucle, alors voici une:

my.sample <- function(x, thresh) { 
    out <- x 
    i <- 1 
    for (j in seq_along(x)[-1]) { 
     if (abs(x[i]-x[j]) >= thresh) { 
     i <- j 
     } else { 
     out[j] <- NA 
     } 
    } 
    out[!is.na(out)] 
} 

my.sample(x = c(1:5,1:4), thresh = 2) 
# [1] 1 3 5 1 3 
+0

Je pense qu'il peut y avoir une approche utilisant '' outer' et qui (..., arr.ind = TRUE) '. – mnel

+0

Probablement, mais d'un point de vue de la complexité, mon algorithme est linéaire alors que 'outer' est O (n^2). J'imagine qu'un algorithme O (n^2) codé efficacement utilisant R (vectorisation, etc.) pourrait être plus rapide que le mien, mais pas que «n» devienne grand. – flodel

+0

Bon point. Je ne suis pas près d'une machine sur laquelle je peux tester. – mnel

1

Vous pouvez le faire sans une boucle en utilisant un peu de récursion:

vsearch = function(v, x, fun=NULL) { 
    # v: input vector 
    # x: threshold level 

    if (!length(v) > 0) return(NULL) 

    y = v-rep(v[1], times=length(v)) 
    if (!is.null(fun)) y = fun(y) 

    i = which(y >= x) 

    if (!length(i) > 0) return(NULL) 
    i = i[1] 

    return(c(v[i], vsearch(v[-(1:(i-1))], x, fun=fun))) 
} 

Avec votre vecteur ci-dessus:

> vsearch(c(1,2,3,4,5,1,2,3,4), 2, abs) 
[1] 3 5 1 3