2011-02-06 10 views
8

Estoy buscando una manera de terminar una función de aplicar temprano en alguna condición. Utilizando un bucle, algo así como:Terminar una función basada en la aplicación anticipadamente (¿similar a romper?)

FDP_HCFA = function(FaultMatrix, TestCosts, GenerateNeighbors, RandomSeed) {  
    set.seed(RandomSeed) 

    ## number of tests, mind the summary column 
    nT = ncol(FaultMatrix) - 1 
    StartingSequence = sample(1:nT) 
    BestAPFD = APFD_C(StartingSequence, FaultMatrix, TestCosts) 
    BestPrioritization = StartingSequence 
    MakingProgress = TRUE 
    NumberOfIterations = 0 
    while(MakingProgress) { 
    BestPrioritizationBefore = BestPrioritization 
    AllCurrentNeighbors = GenerateNeighbors(BestPrioritization) 

    for(CurrentNeighbor in AllCurrentNeighbors) { 
     CurrentAPFD = APFD_C(CurrentNeighbor, FaultMatrix, TestCosts) 

     if(CurrentAPFD > BestAPFD) { 
     BestAPFD = CurrentAPFD 
     BestPrioritization = CurrentNeighbor    
     break 
     } 
    } 

    if(length(union(list(BestPrioritizationBefore), 
        list(BestPrioritization))) == 1) 
     MakingProgress = FALSE 

    NumberOfIterations = NumberOfIterations + 1 
    } 
} 

me gustaría volver a escribir esta función utilizando alguna derivación de apply. En particular, terminar la evaluación de la primera persona con una mejor forma física, evitando así el costo de considerar al resto de la población.

+2

Es posible que pueda utilizar alguna combinación de signalCondition/tryCatch/etc., Pero parece complicado. Yo haría una segunda pregunta de JoshUlrich. –

+2

-1 para publicar código que no es reproducible y tiene un error de sintaxis. –

+0

Lo siento, solo intentaba dar una idea general de lo que estaba buscando, pensé que el fragmento sería suficiente. – user602319

Respuesta

1

Aparte de hacer que funcione su código de muestra * Creo que este es un caso claro en el que un ciclo es la opción correcta. Aunque R puede aplicar una función a un vector completo de variables [EDITAR: pero debe decidir cuáles son antes de aplicar], en este caso utilizaría un bucle while para evitar el costo de ejecutar repeticiones innecesarias. Advertencia: Sé que for bucles se han comparado favorablemente con apply en las pruebas de tiempo, pero no he visto una prueba similar para while. Vea algunas de las opciones en http://cran.r-project.org/doc/manuals/R-lang.html#Control-structures.

while (*statement1*) *statement2* 

18

tengo por cierto que no se sabe muy captar la familia apply y su propósito. Al contrario de la idea general, son no el equivalente de cualquier for -loop. Se puede decir que la mayoría de las bifurcaciones for son equivalentes a apply, pero esa es otra cuestión.

Apply hace exactamente lo que dice: aplica una función secuencialmente en varios argumentos similares y devuelve el resultado. Por lo tanto, por definición no puede salir de una aplicación. Ya no estás operando en el entorno global, por lo que en principio no puedes mantener contadores globales, verificar después de cada ejecución alguna condición y adaptar el ciclo. Puede acceder al entorno global e incluso cambiar variables usando assign o <<-, pero esto es bastante peligroso.

Para entender la diferencia, no lea apply(1:3,afunc) como for(i in 1:3) afunc(i), sino como

afunc(1) 
afunc(2) 
afunc(3) 

en una declaración (bloque). Eso refleja mejor lo que estás haciendo exactamente. Un equivalente para break en un apply simplemente no tiene sentido, ya que es más un bloque de código que un bucle.

0

También estaba buscando una manera de salir temprano de un bucle basado en la aplicación, y encontré este hilo.

A pesar de que algunas personas afirman que se aplican deben ser considerados como "código de bloque" en lugar de un "bucle", sigo pensando que sería útil tener una posibilidad de salir de ella. La razón es que las funciones basadas en aplicar parecen ejecutar mucho más rápido, algo así como 10-100 veces más rápido que un bucle for. Muchas veces He ejecutado fragmentos simples en bucles que no se hacen después de más de unos minutos, mientras que la aplicación parece obtener el mismo trabajo en cuestión de segundos.

+0

Hmm ... bueno, creo que pude haber visto una o dos publicaciones que debatirían su afirmación, pero la velocidad no era lo que buscaba aquí (bueno, no es que me quejara). Estoy trabajando en algunos algoritmos basados ​​en búsqueda en R, y las funciones en el paquete plyr permiten la función paralela/distribuida a través de foreach con .parallel arg. Eso permite la experimentación (fácil) en eficiencia con paralelismo en varios niveles en los algoritmos. – user602319

Cuestiones relacionadas