junit-quickcheck - 生成保持深度有限的随机树
junit-quickcheck - generating random trees keeping the depth finite
我正在练习junit-quickcheck
我已经为二叉树的三个排序组件(Node
、Leaf
、Empty
)准备了生成器。
我希望创建随机树并验证它们的属性。
Node
s 的生成器根据特定概率为其两个分支选择更多生成器。
但是,我希望树木在每个 运行 期间的某个时间停止生长。构建 Node
子树的概率必须随着世代的发展而降低。
我希望能够通过使用 GenerationStatus
来控制树的深度,但我看不出具体如何。
另一种假设是在generate()
之前调用下一个生成器的方法configure()
,但我还没有成功。
实现这一切的正确方法是什么?
您可以使用 GenerationStatus#setValue(Key, Object)
在生成器之间传递值。
这是我写的一个例子,它生成严格递减的正整数列表:
import com.pholser.junit.quickcheck.generator.GenerationStatus;
import com.pholser.junit.quickcheck.generator.Generator;
import com.pholser.junit.quickcheck.random.SourceOfRandomness;
import java.util.ArrayList;
import java.util.List;
public class ListGenerator extends Generator<List<Integer>> {
private static final int MAX_VALUE = 100;
private static final GenerationStatus.Key<Integer> PREVIOUS_KEY = new GenerationStatus.Key<>("previous", Integer.class);
@SuppressWarnings("unchecked")
public ListGenerator() {
super((Class<List<Integer>>) (Class) List.class);
}
public List<Integer> generate(SourceOfRandomness sourceOfRandomness, GenerationStatus generationStatus) {
List<Integer> result = new ArrayList<>();
int previous = generationStatus.valueOf(PREVIOUS_KEY).orElse(MAX_VALUE);
int current = sourceOfRandomness.nextInt(previous);
if (current > 0) {
result.add(current);
generationStatus.setValue(PREVIOUS_KEY, current);
Generator<List<Integer>> listGen = gen().make(ListGenerator.class);
result.addAll(listGen.generate(sourceOfRandomness, generationStatus));
generationStatus.setValue(PREVIOUS_KEY, null);
}
return result;
}
}
你如何生成一个(有界的)值列表以放入树中,并从这些值组成树。那么你肯定知道这个结构是有界的。
您可能需要注意平衡树,以防简单地按顺序调用 add
可能会产生高度不平衡的树,但这取决于您的树实现。
与 Helder-Pereira 的 类似,不需要递归生成器:我会生成一个整数列表并对列表进行排序。
我正在练习junit-quickcheck
我已经为二叉树的三个排序组件(Node
、Leaf
、Empty
)准备了生成器。
我希望创建随机树并验证它们的属性。
Node
s 的生成器根据特定概率为其两个分支选择更多生成器。
但是,我希望树木在每个 运行 期间的某个时间停止生长。构建 Node
子树的概率必须随着世代的发展而降低。
我希望能够通过使用 GenerationStatus
来控制树的深度,但我看不出具体如何。
另一种假设是在generate()
之前调用下一个生成器的方法configure()
,但我还没有成功。
实现这一切的正确方法是什么?
您可以使用 GenerationStatus#setValue(Key, Object)
在生成器之间传递值。
这是我写的一个例子,它生成严格递减的正整数列表:
import com.pholser.junit.quickcheck.generator.GenerationStatus;
import com.pholser.junit.quickcheck.generator.Generator;
import com.pholser.junit.quickcheck.random.SourceOfRandomness;
import java.util.ArrayList;
import java.util.List;
public class ListGenerator extends Generator<List<Integer>> {
private static final int MAX_VALUE = 100;
private static final GenerationStatus.Key<Integer> PREVIOUS_KEY = new GenerationStatus.Key<>("previous", Integer.class);
@SuppressWarnings("unchecked")
public ListGenerator() {
super((Class<List<Integer>>) (Class) List.class);
}
public List<Integer> generate(SourceOfRandomness sourceOfRandomness, GenerationStatus generationStatus) {
List<Integer> result = new ArrayList<>();
int previous = generationStatus.valueOf(PREVIOUS_KEY).orElse(MAX_VALUE);
int current = sourceOfRandomness.nextInt(previous);
if (current > 0) {
result.add(current);
generationStatus.setValue(PREVIOUS_KEY, current);
Generator<List<Integer>> listGen = gen().make(ListGenerator.class);
result.addAll(listGen.generate(sourceOfRandomness, generationStatus));
generationStatus.setValue(PREVIOUS_KEY, null);
}
return result;
}
}
你如何生成一个(有界的)值列表以放入树中,并从这些值组成树。那么你肯定知道这个结构是有界的。
您可能需要注意平衡树,以防简单地按顺序调用 add
可能会产生高度不平衡的树,但这取决于您的树实现。
与 Helder-Pereira 的