junit-quickcheck - 生成保持深度有限的随机树

junit-quickcheck - generating random trees keeping the depth finite

我正在练习junit-quickcheck

我已经为二叉树的三个排序组件(NodeLeafEmpty)准备了生成器。

我希望创建随机树并验证它们的属性。

Nodes 的生成器根据特定概率为其两个分支选择更多生成器。

但是,我希望树木在每个 运行 期间的某个时间停止生长。构建 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 的 类似,不需要递归生成器:我会生成一个整数列表并对列表进行排序。