7

He escrito un generador de permutación para las listas de Scala que genera todas las permutaciones de una lista dada. Hasta ahora, tengo lo siguiente basado en this Haskell implementation (y creo que es más eficiente que varias otras opciones que he probado). ¿Hay alguna forma de hacer esto aún más eficiente, o he cubierto todas mis bases?Generador de permutación más rápido

/** For each element x in List xss, returns (x, xss - x) */ 
    def selections[A](xss:List[A]):List[(A,List[A])] = xss match { 
     case Nil => Nil 
     case x :: xs => 
     (x, xs) :: (for((y, ys) <- selections (xs)) 
      yield (y, x :: ys)) 
    } 

    /** Returns a list containing all permutations of the input list */ 
    def permute[A](xs:List[A]):List[List[A]] = xs match { 
     case Nil => List(Nil) 

     //special case lists of length 1 and 2 for better performance 
     case t :: Nil => List(xs) 
     case t :: u :: Nil => List(xs,List(u,t)) 

     case _ => 
     for ((y,ys) <- selections(xs); ps <- permute(ys)) 
      yield y :: ps 
    } 
+1

¿Es esto más rápido que el método de intercambio basado en matrices? ¿O quiere decir "generador de permutación funcional más rápido"? (Nunca lo dices explícitamente, pero agregaste la etiqueta ....) –

+0

Me refiero al generador de permutación funcional más rápido. Por esa razón, no he intentado comparar esto con el método de intercambio basado en matrices. –

+0

Hay mejores algoritmos. Vi uno aquí en Stack Overflow no hace mucho tiempo, en Scala, que devolvió la siguiente permutación (asumiendo un conjunto de índices), en lugar de una lista de todas las permutaciones. Usó 'partition' para encontrar el punto de la siguiente permutación del índice, y generalmente evitó las llamadas recursivas sin cola. Además, por supuesto, la implementación de Haskell del código que ha mostrado funcionaría muy rápido, porque no computaría nada por adelantado. :-) –

Respuesta

3

En Scala 2,9 improvisada haber añadido algunos métodos útiles a clase de colección Scala, incluyen un Seq.permutations que la generación de todas las permutaciones de este ss. Ver link text. Y tengo una implementación no recursiva que creo que tendría un mejor rendimiento. Consulte A non-recursive implementation of SeqLike.permutations

+0

Bueno, la versión en Scala 2.9 svn ahora parece ser similar a la mía en su implementación, solo se queda sin memoria tratando de permutar una lista de 10 elementos, y tiene un rendimiento mucho peor que el mío. Su versión es más lenta que la mía para listas cortas (5 elementos), pero más rápida para listas más largas (10 elementos). Además, usa menos memoria a la vez, porque devuelve un iterador. –

+0

Para mi caso de uso, ralentizaría las cosas para intentar eliminar duplicados, porque presumiblemente no hay duplicados, y '==' en mis objetos lleva mucho tiempo (aunque los puntos de referencia que analizo aquí se realizaron con una Lista [Int. ]). –

+0

Sí, Extempore o mi implementación está disponible para Seq con duplicados, p. Lista (1,1,1,2,2,2) – Eastsun