2

scalacheck でシャッフルされたシーケンスを生成しようとしています。Scalacheck には、それを直接行うためのジェネレーターが用意されていません。また、オンラインで簡単な答えを見つけることができませんでした。少し考えた後、以下は私がやった方法です。役に立つかどうか他の人が見つけてくれることを願っています。

4

3 に答える 3

3

コレクションのシャッフル アルゴリズム (scala.util.Random にあるものなど) を使用して、より明確な解決策を得ることができます。

/**
 * This represents a potential list shuffling. It
 * acts as a pure function - when applied to the
 * same list it always returns the same result
 */
class Shuffling(seed: Int) {
  def apply[T](xs: Seq[T]): Seq[T] = {
    val r = new scala.util.Random(seed)
    r.shuffle(xs)
  }
}

import org.scalacheck.Arbitrary._
import org.scalacheck.Gen

val shufflingGen: Gen[Shuffling] = arbitrary[Int].map(new Shuffling(_))

上記のスニペットはshuffling、リストの可能な並べ替えを定義しています。また、任意のシャッフル インスタンスを提供するジェネレータも定義します。次の例は、シャッフルを使用して整数の範囲を並べ替える方法を示しています。

def shuffledRange(n: Int): Gen[Seq[Int]] = {
  for {
    shuffling <- shufflingGen
  } yield shuffling(Range(0, n))
}

Shufflingクラスの形で 1 レベルの間接性を追加するのは奇妙に思えるかもしれませんRandom.shuffle。リストに直接適用することもできます。これは、Scalacheck がすでにバックグラウンドで実行している暗黙のランダム化に加えて、追加のランダム性のソースを回避したいためです。シャッフルのランダム性のソースは、scalacheck ジェネレーターに由来します。

これの利点の 1 つは、生成されたケースの再現性です (Scalacheckがサポートする場合はいつでも)。

于 2016-01-19T17:24:42.733 に答える
2

org.scalacheck.Gen.pick(n: Int, l: Iterable[T]): Gen[Seq[T]]からランダムな順序でn個別の要素を選択します。lで呼び出すpickn = l.length、ランダムに生成されます

于 2016-11-28T10:30:52.337 に答える
0
def shuffle[T](s: Seq[T], prefix: Seq[T] = Vector()): Gen[Seq[T]] =
    if (s.length == 0) Gen.const(prefix.toSeq)
    else
      Gen.choose(0, s.length - 1)
        .flatMap { i => 
          shuffle(
            s.take(i) ++ s.takeRight(s.length - i - 1), 
            prefix :+ s(i)) }
于 2015-06-11T09:58:52.257 に答える