我需要在给定范围内生成x个随机奇数。 我知道这可以通过简单的循环来实现,但我不确定哪种方法是最好的,并且有更好的数学方法来解决这个问题。
编辑:我也不能多次使用相同的号码。
答案 0 :(得分:1)
生成超过范围一半的x整数值,并为每个值加倍并添加1.
回答已经修改的问题:1)生成范围内的候选人列表,将其改组,然后取第一个x。或者2)根据我的原始建议生成值,如果生成的值在已生成的值列表中,则拒绝并重试。
如果x是范围的很大一部分,第一个将更好地工作,后者如果x相对于范围较小。
ADDENDUM:之前应该考虑过这种方法,它基于条件概率。我不知道php(我是从“随机”标签来的),所以我将它表示为伪代码:
generate(x, upper_limit)
loop with index i from upper_limit downto 1 by 2
p_value = x / floor((i + 1) / 2)
if rand <= p_value
include i in selected set
decrement x
return/exit if x <= 0
end if
end loop
end generate
x
是要生成的所需数量的值,upper_limit
是范围中最大的奇数,rand
生成0到1之间的均匀分布的随机数。基本上,它会逐步完成候选的奇数组,并根据您仍需要多少值以及仍有多少候选项接受或拒绝每个号码。
我已经测试了这个,它确实有效。与原始接受/拒绝相比,它需要更少的中间存储而不是混洗和更少的迭代。
答案 1 :(得分:0)
生成范围内的元素列表,删除随机系列中所需的元素。重复x次。
或者您可以生成一个范围内有奇数的数组,然后进行随机播放
生成很简单:
$range_array = array();
for( $i = 0; $i < $max_value; $i++){
$range_array[] .= $i*2 + 1;
}
随机
shuffle( $range_array );
拼出x个第一个元素。
$result = array_slice( $range_array, 0, $x );
这是一个完整的解决方案。
答案 2 :(得分:0)
function mt_rands($min_rand, $max_rand, $num_rand){
if(!is_integer($min_rand) or !is_integer($max_rand)){
return false;
}
if($min_rand >= $max_rand){
return false;
}
if(!is_integer($num_rand) or ($num_rand < 1)){
return false;
}
if($num_rand <= ($max_rand - $min_rand)){
return false;
}
$rands = array();
while(count($rands) < $num_rand){
$loops = 0;
do{
++$loops; // loop limiter, use it if you want to
$rand = mt_rand($min_rand, $max_rand);
}while(in_array($rand, $rands, true));
$rands[] = $rand;
}
return $rands;
}
// let's see how it went
var_export($rands = mt_rands(0, 50, 5));
代码未经过测试。刚写完了。可以改进一点,但这取决于你。
答案 3 :(得分:0)
此代码在区间[1,20]中生成5个奇数唯一数字。根据您的需要更改$ min,$ max和$ n = 5.
<?php
function odd_filter($x)
{
if (($x % 2) == 1)
{
return true;
}
return false;
}
// seed with microseconds
function make_seed()
{
list($usec, $sec) = explode(' ', microtime());
return (float) $sec + ((float) $usec * 100000);
}
srand(make_seed());
$min = 1;
$max = 20;
//number of random numbers
$n = 5;
if (($max - $min + 1)/2 < $n)
{
print "iterval [$min, $max] is too short to generate $n odd numbers!\n";
exit(1);
}
$result = array();
for ($i = 0; $i < $n; ++$i)
{
$x = rand($min, $max);
//not exists in the hash and is odd
if(!isset($result{$x}) && odd_filter($x))
{
$result[$x] = 1;
}
else//new iteration needed
{
--$i;
}
}
$result = array_keys($result);
var_dump($result);