两次Math.Random 取最大最小的含义
random是等概率的返回[0-1)的数,所以概率是x,如果想要概率是x的平方,就要用到max.
Math.max( random() , random() )
random(), 返回0-x范围的数,概率x
因为返回的是最大值,所以想让最终结果在0-x范围上,需要两次random都返回0-x范围的数字,有一次例外,最终结果就会不在0-x范围上,因为取max嘛。所以,套了max之后的过程,就把得到0-x范围的数字,概率调整到了x平方,也就是两次都得命中才行。
Math.min( random() , random() )
random(), 返回0-x范围的数,概率x
因为返回的是最小值,所以想让最终结果在0-x范围上,两次random中,有任何一次返回0-x范围的数字,最终结果就会在0-x范围上,因为取min嘛。只有两次都不在0-x范围上,最终结果才会得不到0-x范围上的数字。
random(),返回不在0-x范围的数,概率是1-x。
所以两次都不在,概率是(1-x)的平方。
所以有任何一次在,概率是:1-(1-x)的平方。
所以,套了min之后的过程,就把得到0-x范围的数字,概率调整到了,1-(1-x)的平方,也就是两次之中有一次命中就可以。
二、random基础算法练习题
从1~5随机到1~7随机
从a~b随机到c~d随机
01不等概率随机到01等概率随机
因为random是等概率返回一个数,假如有一个黑盒函数f()是等概率返回1-5,那么如何获得等概率获得1-7的函数呢?
// 此函数只能用,不能修改 // 等概率返回1~5 public static int f() { return (int) (Math.random() * 5) + 1; } // 等概率得到0和1 public static int a() { 因为我可以获得1-5的函数,那么我可以让 1-2 返回0, 4-5 返回 1, 3我让他重新选。 这样我可以根据f()函数获得一个等概率返回0或者1的函数 int ans = 0; do { ans = f(); } while (ans == 3); return ans < 3 ? 0 : 1; } // 等概率返回0~6 public static int b() { 然后 我就可以通过二进制算出0-6的函数, 因为二进制不是0就是1, 所以三个二进制代表的数 0-7 int ans = 0; do { ans = (a() << 2) + (a() << 1) + a(); 这样通过左移 三个二进制位,就会因为 0或者1 的等概率出现, 变成0-7的等概率出现 } while (ans == 7); 如果是7,我可以重新选,这样就获得了0-6的等概率随机数 , 注意这里也可以直接如果是0的话就重选,这样1-7的等概率出现的函数就可以获得了 return ans; } // 等概率返回1~7 public static int c() { 根据,原理就可以随意的对某些范围的数,写出函数,关键是要 获得等概率出现0或者1的函数 return b() + 1; }