如何基于Apache分布(Breeze)生成可重复的Triangular随机DenseVector
解决TriangularDistribution生成可重复DenseVector的问题
问题核心在于Apache Commons Math的TriangularDistribution不会自动复用Breeze的RandBasis随机源,而Breeze也没有为该分布提供原生构造器支持,导致你遇到的两种问题。以下是可行的解决方案:
步骤1:复用Breeze的带种子随机源
首先保留你定义的隐式RandBasis,从中提取出Apache分布类可接受的Random实例:
import breeze.math.RandBasis import org.apache.commons.math3.distribution.TriangularDistribution import breeze.linalg.DenseVector implicit val randBasis = RandBasis.withSeed(2022) // 获取Breeze使用的带种子Random实例 val breezeRandom = randBasis.rand.getRandom
步骤2:创建带指定随机源的TriangularDistribution
将提取的Random传入TriangularDistribution的构造器,确保分布使用固定种子的随机源:
val triangularDist = new TriangularDistribution(breezeRandom, 10, 15, 20)
步骤3:生成可重复的DenseVector
使用Breeze的DenseVector.tabulate方法生成指定长度的采样向量:
val triangularRandoms = DenseVector.tabulate(100)(_ => triangularDist.sample())
封装复用(可选)
如果需要多次使用,可以封装成类似Breeze原生分布的方法:
def triangularSamplesVector(lower: Double, mode: Double, upper: Double, size: Int)(implicit randBasis: RandBasis): DenseVector[Double] = { val random = randBasis.rand.getRandom val dist = new TriangularDistribution(random, lower, mode, upper) DenseVector.tabulate(size)(_ => dist.sample()) } // 调用示例 val triangularRandoms = triangularSamplesVector(10, 15, 20, 100)
为什么之前的方法失效?
- 直接
new TriangularDistribution(10,15,20)会使用Apache默认的无种子Random实例,每次运行都会重新初始化随机状态,导致结果不重复。 - 去掉
new关键字时,Breeze没有为Apache的TriangularDistribution提供对应的构造隐式实现(即报错中的Impl3),因此无法像原生的Uniform/Gaussian那样直接调用构造器。
内容的提问来源于stack exchange,提问作者Samik R
相关产品推荐
相关产品推荐

