PHP在一个范围内生成x个随机奇数

时间:2013-06-16 23:09:58

标签: php random numbers

我需要在给定范围内生成x个随机奇数。 我知道这可以通过简单的循环来实现,但我不确定哪种方法是最好的,并且有更好的数学方法来解决这个问题。

编辑:我也不能多次使用相同的号码。

4 个答案:

答案 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);