Java 跳跃列表生成器使用哪个 C++ 随机数分布?
Which C++ random number distribution to use for the Java skip list generator?
JavaConcurrentSkipListMap
class包含一个方法randomLevel
,根据多处理器编程艺术[=25=,输出以下内容]:
The randomLevel()
method is designed based on empirical measurements to maintain the skiplist property.
For example, in the java.util.concurrent
package, for a maximal SkipList level of 31, randomLevel()
returns 0 with probability 3/4, i with probability 2^(−(i+2)) for i ∈ [1, 30], and 31 with probability 2^−32.
这个看起来像geometric distribution,但不完全是。有什么方法可以根据提供的随机分布巧妙地定义它,还是我必须自己进行操作,例如:
inline unsigned randomLevel() {
auto randNum = distribution.operator()(engine); // distribution is std::uniform_int_distribution<>
unsigned two__30{0x4000'0000};
if (randNum == 0)
return 31; // p(level == 31) = 2**-31
else if (randNum >= two__30)
return 0; // p(level = 0) = 0.75
else
return 30 - static_cast<unsigned>(log2(randNum)); // p(level = i) = 2**-(i+2)
}
This looks like a geometric distribution, but not quite.
你是对的,但问题只是 0
的概率。请注意,您可以通过将前两个值合并为一个来使用 std::geometric_distribution
。
class RandomLevel
{
std::geometric_distribution<unsigned> distribution;
std::mt19937 gen{std::random_device{}()};
public:
unsigned operator()() {
auto result = distribution(gen);
return result > 1u : result - 1u : 0u;
}
}
JavaConcurrentSkipListMap
class包含一个方法randomLevel
,根据多处理器编程艺术[=25=,输出以下内容]:
The
randomLevel()
method is designed based on empirical measurements to maintain the skiplist property. For example, in thejava.util.concurrent
package, for a maximal SkipList level of 31,randomLevel()
returns 0 with probability 3/4, i with probability 2^(−(i+2)) for i ∈ [1, 30], and 31 with probability 2^−32.
这个看起来像geometric distribution,但不完全是。有什么方法可以根据提供的随机分布巧妙地定义它,还是我必须自己进行操作,例如:
inline unsigned randomLevel() {
auto randNum = distribution.operator()(engine); // distribution is std::uniform_int_distribution<>
unsigned two__30{0x4000'0000};
if (randNum == 0)
return 31; // p(level == 31) = 2**-31
else if (randNum >= two__30)
return 0; // p(level = 0) = 0.75
else
return 30 - static_cast<unsigned>(log2(randNum)); // p(level = i) = 2**-(i+2)
}
This looks like a geometric distribution, but not quite.
你是对的,但问题只是 0
的概率。请注意,您可以通过将前两个值合并为一个来使用 std::geometric_distribution
。
class RandomLevel
{
std::geometric_distribution<unsigned> distribution;
std::mt19937 gen{std::random_device{}()};
public:
unsigned operator()() {
auto result = distribution(gen);
return result > 1u : result - 1u : 0u;
}
}