【算法导论学习-009】仅使用Random(0,1)实现Random(a,b)

本文介绍了如何仅使用Random(0,1)来实现Random(a,b)的均匀分布随机数生成算法,并通过实例分析了算法的正确性与运行时间。通过Java代码验证了实现细节。

《算法导论》P117课后题5.1-2

   Describe an implementation of the procedure Random(a, b) that only makes calls to Random(0,1). What is the expected running time of your procedure, as a function of a and b? The probability of the result of Random(a,b) should be pure uniformly distributed, as Random(0,1)

    该问题的讨论区:http://stackoverflow.com/questions/8692818/how-to-implement-randoma-b-with-only-random0-1

    该问题关键点是Random(a, b)生成的随机数在[a, b]中均匀分布,讨论区有两类典型错误。

    第一类错误:

for i = 1 to b-a
    r = a + Random(0,1)
return r
  第二类错误:

r = a
for i = 1 to b - a //including b-a
    r += Random(0,1)
return r
正确方法:

1) Find the smallest number, p, such that 2^p > b-a.

2) Perform the following algorithm:

r=0
for i = 1 to p
    r = 2*r + Random(0,1)

3) If r is greater than b-a, go to step 2.

4) Your result is r+a

So let's try Random(1,3).
So b-a is 2.
2^1 = 2, so p will have to be 2 so that 2^p is greater than 2. 
So we'll loop two times. Let's try all possible outputs:

00 -> r=0, 0 is not > 2, so we output 0+1 or 1.
01 -> r=1, 1 is not > 2, so we output 1+1 or 2.
10 -> r=2, 2 is not > 2, so we output 2+1 or 3.
11 -> r=3, 3 is > 2, so we repeat.
  在此我用java测试如下:
/**
 * 创建时间:2014年8月10日 下午2:48:08 项目名称:Test
 * 
 * @author Cao Yanfeng
 * @since JDK 1.6.0_21 类说明:
 */

public class RandomNumbersTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(getRandomNumber(1, 3));
	}

	/*
	 * new Random().nextInt(2)用来模拟Random(0,1),注意new
	 * Random().nextInt(2)表示生成≥0且<2的数,即生成0或1
	 */
	public static int getRandomNumber(int a, int b) {
		int diff = b - a;
		int p = getP(diff);
		int result = 0;
		for (int i = 1; i <= p; i++) {
			int random = new Random().nextInt(2);
			result = 2 * result + random;
			/* 如果r大于b-a,重复第2)步 */
			if (result > diff) {
				result = 0;
				i = 1;
			}
		}
		return result + a;
	}

	/* 获得最小的p,使得2^p>b-a */
	public static int getP(int diff) {
		for (int i = (int) Math.ceil(Math.log(diff) / Math.log(2));; i++) {
			if ((Math.pow(2, i)) > diff) {
				return i;
			}
		}
	}

}



### 关于《算法导论》Problems 5-1 的解答与分析 Problems 5-1 是关于概率分析和随机化算法的内容,主要讨论如何利用概率分布设计高效的算法。以下是对此问题的详细解析: #### 随机化算法的核心概念 随机化算法通过引入随机性来提高效率或简化复杂度。这类算法通常依赖于某些特定的概率模型[^1]。例如,在解决问题时,可以通过随机选择输入的一部分数据来进行初步计算,从而减少不必要的运算。 #### Problems 5-1 的具体描述 此问题要求我们考虑一个数组中的最大值寻找问题,并探讨不同策略下的期望运行时间。假设有一个长度为 \( n \) 的数组,其中每个元素独立且均匀分布在某个区间内。我们需要评估两种不同的方法: 1. **顺序扫描法**:逐一比较每个元素的最大值。 2. **随机采样法**:先从数组中随机抽取若干样本,再基于这些样本估计全局最大值的位置。 对于上述两种方案,我们可以分别推导它们的时间复杂度以及误差范围。 #### 方法一:顺序扫描法 这种方法非常直观,即依次遍历整个列表并记录当前遇到过的最高数值。由于每次迭代需常数级操作,因此总耗时为线性的 \( O(n) \)[^1]。 #### 方法二:随机采样法 这里采用的是更复杂的统计学原理&mdash;&mdash;蒙特卡罗模拟技术。基本流程如下: - 设定抽样数量 k; - 对原始集合执行多次独立取样动作; - 综合所有获取的小批次峰值信息得出最终结论。 尽管如此做可能会带来一定偏差,但它显著降低了实际开销至接近 \( O(k) \),特别是当 k 远小于 n 时效果尤为明显[^3]。 下面给出一段简单的 Python 实现代码展示第二种方法的工作机制: ```python import random def estimate_max_random_sampling(array, sample_size): max_estimated = float('-inf') sampled_indices = set(random.sample(range(len(array)), min(sample_size, len(array)))) for index in sampled_indices: if array[index] > max_estimated: max_estimated = array[index] return max_estimated ``` 值得注意的是,虽然这段程序能够快速提供近似解,但在极端情况下仍有可能漏掉真正的极值点[^2]。 --- ### 结果对比与总结 通过对这两种途径深入剖析可知,传统枚举手段固然精确可靠却缺乏灵活性;而借助几率推测虽牺牲了一部分准确性但却极大提升了性能表现。究竟选用哪一类取决于应用场景的具体需求权衡利弊之后决定最为合适的选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值