biased 0.1.1

A Rust library for generating biased random numbers, useful for simulations and weighted selections. 一个用于生成偏向性随机数的 Rust 库,适用于模拟和加权选择场景。
Documentation

English | 中文


biased - Biased Random Number Generation in Rust

Table of Contents


biased - Rust 中的偏向性随机数生成

目录


Project Significance

The biased library provides a simple yet effective way to generate random numbers with a configurable bias towards lower values. This is particularly useful in simulations, game development, statistical modeling, and scenarios where certain outcomes need to be favored without completely eliminating the possibility of others. For instance, in a game, you might want common items to drop more frequently than rare ones, or in a simulation, you might model events that are more likely to occur under specific conditions.

项目意义

biased 库提供了一种简单而有效的方法来生成偏向于较小值的随机数。这在模拟、游戏开发、统计建模以及需要偏向某些结果但又不完全消除其他可能性的场景中特别有用。例如,在游戏中,您可能希望常见物品的掉落率高于稀有物品;在模拟中,您可能需要模拟在特定条件下更可能发生的事件。

Usage Demonstration

The core functionality is provided by the biased_random function, which takes an upper bound N and a BIAS factor. A higher BIAS value increases the probability of generating numbers closer to 0. Below is an example demonstrating its usage and the resulting distribution, similar to the provided test case.

使用演示

核心功能由 biased_random 函数提供,该函数接受一个上限 N 和一个偏向因子 BIASBIAS 值越高,生成接近 0 的数字的概率越大。下面是一个演示其用法和结果分布的示例,类似于提供的测试用例。

#![feature(doc_auto_cfg)]
#![feature(doc_cfg)]

use rand::Rng;

/// Generate a non-uniformly distributed random integer in the range [0, n).
/// The distribution is controlled by a bias parameter, which makes smaller integers more likely to be generated.
/// 生成一个在 [0, n) 区间内非均匀分布的随机整数。
/// 通过一个偏向参数 (bias) 来控制分布,使得数值越小的整数生成的概率越高。
///
/// # Arguments
///
/// * `n` - The upper bound (exclusive) for the random number. Must be a positive integer greater than 0.
///         - `n`: 随机数上限(不包含),必须是大于0的正整数。
/// * `bias` - The bias strength parameter. Must be a positive number.
///          - `bias > 1`: Smaller numbers are more likely. The larger the bias, the more skewed the result is towards 0.
///          - `bias = 1`: Approaches a standard uniform distribution.
///          - `0 < bias < 1`: Larger numbers are more likely.
///          - `bias`: 偏向强度参数,必须是正数。
///            - `bias > 1`: 数值越小概率越高。bias越大,结果越偏向0。
///            - `bias = 1`: 接近标准均匀分布。
///            - `0 < bias < 1`: 数值越大概率越高。
///
/// # Returns
///
/// A random integer in the [0, n) range.
/// 返回一个在 [0, n) 区间内的随机整数。
pub fn biased_random(n: u32, bias: f64) -> u32 {
  if n <= 1 {
    return 0;
  }

  // 1. Get a standard uniform random number in [0, 1).
  // 1. 获取一个 [0, 1) 之间的标准均匀分布随机数。
  let rng: f64 = rand::rng().random();

  // 2. "Warp" the distribution using a power function.
  //    When bias > 1, this pushes most of the results towards 0.
  // 2. 使用幂函数来“扭曲”这个分布。
  //    当 bias > 1 时,这个操作会把大部分结果值推向 0。
  let biased_rng = rng.powf(bias);

  // 3. Map the biased random number from the [0, 1) range to the integer range [0, n).
  // 3. 将 [0, 1) 范围内的偏向随机数映射到 [0, n) 的整数范围。
  (biased_rng * n as f64) as u32
}

// Example usage (from tests/main.rs)
use std::collections::BTreeMap;
use anyhow::Result;
use biased::biased_random;
use log::info;

fn main() -> Result<()> {
  const N: u32 = 20; // Upper bound
  const BIAS: f64 = 3.0; // Bias factor
  const SAMPLES: u32 = 10000; // Number of samples

  info!(
    "> Generating {} biased random numbers (n={}, bias={})",
    SAMPLES, N, BIAS
  );

  let mut histogram = BTreeMap::new();
  for _ in 0..SAMPLES {
    let num = biased_random(N, BIAS);
    *histogram.entry(num).or_insert(0) += 1;
  }

  let max_freq = histogram.values().max().cloned().unwrap_or(0);
  const MAX_BAR_WIDTH: usize = 50;

  info!("> ASCII Histogram of the results:");

  for i in 0..N {
    let freq = histogram.get(&i).cloned().unwrap_or(0);
    let bar_width = if max_freq > 0 {
      (freq as usize * MAX_BAR_WIDTH) / max_freq as usize
    } else {
      0
    };
    let bar: String = "".repeat(bar_width);
    let percentage = (freq as f64 / SAMPLES as f64) * 100.0;
    info!("{:>3}: {:<5} ({:>5.2}%) |{}", i, freq, percentage, bar);
  }

  Ok(())
}

Design Philosophy and Technology Stack

The biased library is designed with simplicity and efficiency in mind. It leverages Rust's strong type system and performance characteristics to provide a reliable random number generation utility. The core algorithm uses a power function to introduce the bias, allowing for fine-grained control over the distribution. The project adheres to modern Rust practices, utilizing cargo add for dependency management and parking_lot for efficient locking if concurrency were introduced. Error handling is managed via anyhow for simplicity in examples and thiserror for structured errors within the library itself (though not extensively used in this minimal example). Logging is handled by the log crate, with log_init for easy initialization.

设计理念与技术栈

biased 库的设计理念是简洁和高效。它利用 Rust 强大的类型系统和性能特性,提供了一个可靠的随机数生成工具。核心算法使用幂函数引入偏向,从而实现对分布的精细控制。项目遵循现代 Rust 实践,使用 cargo add 进行依赖管理,并在引入并发时使用 parking_lot 进行高效锁定。错误处理通过 anyhow 在示例中简化,并通过 thiserror 在库内部进行结构化错误管理(尽管在此最小示例中未广泛使用)。日志记录由 log crate 处理,并使用 log_init 方便初始化。

File Structure

The project follows a standard Rust library structure:

.
├── Cargo.toml        # Project manifest and dependencies
├── README.mdt        # This documentation file
├── src/
│   └── lib.rs        # Core library logic (biased_random function)
└── tests/
    └── main.rs       # Integration tests and usage examples

文件结构

项目遵循标准的 Rust 库结构:

.
├── Cargo.toml        # 项目清单和依赖
├── README.mdt        # 本文档
├── src/
│   └── lib.rs        # 核心库逻辑 (biased_random 函数)
└── tests/
    └── main.rs       # 集成测试和使用示例

Historical Anecdotes

The concept of biased random number generation has roots in various fields, from early statistical experiments to modern Monte Carlo simulations. One interesting historical note is the development of pseudo-random number generators (PRNGs) themselves. Early methods, like the middle-square method proposed by John von Neumann, were often simple but had short periods and poor statistical properties. Over time, more sophisticated algorithms like Mersenne Twister emerged, providing high-quality pseudo-random numbers. Biasing these outputs, as done in this library, adds another layer of control, allowing developers to fine-tune randomness for specific application needs, bridging the gap between pure randomness and deterministic outcomes.

历史趣闻

偏向性随机数生成的概念根植于从早期统计实验到现代蒙特卡洛模拟的各个领域。一个有趣的历史趣闻是伪随机数生成器(PRNGs)本身的发展。早期的方法,如约翰·冯·诺依曼提出的中平方方法,通常很简单,但周期短且统计特性差。随着时间的推移,出现了更复杂的算法,如 Mersenne Twister,提供了高质量的伪随机数。像本库这样对这些输出进行偏向处理,增加了另一层控制,允许开发人员根据特定的应用需求微调随机性,弥合了纯随机性与确定性结果之间的鸿沟。

About

This project is an open-source component of i18n.site ⋅ Internationalization Solution.

关于

本项目为 i18n.site ⋅ 国际化解决方案 的开源组件。