简体   繁体   English

Scalacheck:生成总数小于某个值的数字列表

[英]Scalacheck: generate list of numbers with total less than a certain value

I need to generate a random list of numbers of a given size whose total is less than a given fixed threshold using ScalaCheck.我需要使用 ScalaCheck 生成一个给定大小的随机数字列表,其总数小于给定的固定阈值。 In other words, do something like:换句话说,请执行以下操作:

val threshold = 3000    
val listGenerator = Gen.listOfN(2000, Gen.choose(1,2000)) suchThat { _.sum < theshold }

While the above expresses exactly what I want to achieve, it doesn't work as the suchThat clause ends up discarding the vast majority of generated values.虽然上面准确地表达了我想要实现的目标,但它不起作用,因为 suchThat 子句最终丢弃了绝大多数生成的值。

Well, given your maximum is 3k and you want a list of 2000 with the minimum value of 1, I'd expect a list of mostly 1s and 2s.好吧,鉴于您的最大值是 3k,并且您想要一个 2000 的列表,最小值为 1,我希望列表主要是 1 和 2。 One solution is below (With current numbers will only generate a list of 1s),下面是一种解决方案(使用当前数字只会生成 1 的列表),

val threshold = 3000

val max = 2000
val max = threshold / n

val listGenerator = Gen.listOfN(max, Gen.choose(1,max))

The math would change a bit if you allow 0s.如果您允许 0,数学会有所改变。

Assuming the threshold is T , and the length of the list is N , You can generate this list by picking N + 1 distinct sorted random numbers within 0 until T , and then compute the differences between adjacent numbers.假设阈值为T ,列表的长度为N ,您可以通过在0 until T之间选取N + 1不同的排序随机数来生成此列表,然后计算相邻数字之间的差异。

For example, let T = 10 and N = 3 , generate 4 distinct sorted numbers first:例如,让T = 10N = 3 ,首先生成 4 个不同的排序数:

1, 4, 6, 9

By computing the differences of adjacent numbers, you get:通过计算相邻数字的差异,你得到:

3, 2, 3

whose sum is 8, less than 10.其和为 8,小于 10。

Following this, you can have the following generator:在此之后,您可以拥有以下生成器:

  def gen(T: Int, N: Int): Gen[collection.Seq[Int]] =
    Gen.pick(N + 1, 0 until T).map(_.sortBy(-_)).map { sorted =>
      (sorted.init, sorted.tail).zipped.map(_ - _)
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM