当前位置: 首页 > 知识库问答 >
问题:

从一组给定的数字和机会中生成一个随机数

亢奇
2023-03-14

我有一个数字列表,比如

 $list = array(1,5,19,23,59,51,24) 

在实际代码中,这是从数据库生成的,所以这个数组最多可以容纳500个彼此不同的数字。

数据库中的每个数字都有发生的概率。所以我有一个以前执行的数据来生成从1到500的随机数,并记录了每个数生成1000次的概率。

现在有了数字列表和每个数字的概率,我想写一个函数,根据这些500个数字的概率,从中生成一个随机数。

例如:

    number 1 has a chance of: 0.00123 //0.123%
    number 6 has a chance of: 0.0421 //4.21%
    number 11 has a chance of: 0.0133 //1.33%

所以变量$finallist看起来像这样:

   $finallist[1] = 0.00123;
   $finallist[6] = 0.0421;
   $finallist[11] = 0.0133;

现在,如果我运行我的函数并传入$finallist作为参数,我想检索1到6之间的随机数,但数字6出来的可能性高于1,11出来的可能性高于1。

我编写了一些函数,用于根据随机数的概率返回随机数,但它只接受1个值作为参数。

private function randomWithProbability($chance, $num, $range = false)
{
    /* first generate a number 0 and 1 and see if that number is in the range of chance */
    $rand = $this->getRandomFloatValue(0, 1);

    if ($rand <= $chance) 
    {
        /* the number should be returned */
        return $num;
    }
    else 
    {
        /* otherwise return a random number */
        if ($range !== false)
        {
            /* make sure that this number is not same as the number for which we specified the chance */
            $rand = mt_rand(1, $range);
            while ($rand == $num)
            {
                $rand = mt_rand(1, $range);
            }

            return $rand;
        }
    }
}

如果有人知道这样做的解决方案/算法,或者PHP中内置了什么东西,那将是一个很大的帮助。非常感谢你。

共有1个答案

邢同
2023-03-14

您正在寻找的基本算法:

  • 将所有概率相加,确定最大值

示例代码:

<?php

// create some weighted sample data (id => weight)
$samples = array(
  'a' => 0.001,
  'b' => 0.004,
  'c' => 0.006,
  'd' => 0.05,
  'e' => 0.01,
  'f' => 0.015,
  'g' => 0.1
);

class Accumulator {
   function __construct($samples) {
      // accumulate all samples into a cumulative amount (a running total)
      $this->acc = array();
      $this->ids = array();
      $this->max = 0;
      foreach($samples as $k=>$v) {
         $this->max += $v;
         array_push($this->acc, $this->max);
         array_push($this->ids, $k);
      }
   }

   function pick() {
      // selects a random number between 0 and 1, increasing the multiple here increases the granularity
      // and randomness; it should probably at least match the precision of the sample data (in this case 3 decimal digits)
      $random = mt_rand(0,1000)/1000 * $this->max;
      for($i=0; $i < count($this->acc); $i++) {
         // looks through the values until we find our random number, this is our seletion
         if( $this->acc[$i] >= $random ) {
            return $this->ids[$i];
         }
      }
      throw new Exception('this is mathematically impossible?');
   }

   private $max; // the highest accumulated number
   private $acc; // the accumulated totals for random selection
   private $ids; // a list of the associated ids
}

$acc = new Accumulator($samples);

// create a results object to test our random generator
$results = array_fill_keys(array_keys($samples), 0);

// now select some data and test the results
print "picking 10000 random numbers...\n";
for($i=0; $i < 10000; $i++) {
   $results[ $acc->pick() ]++;
}

// now show what we found out
foreach($results as $k=>$v) {
   print "$k picked $v times\n";
}

结果如下:

> php.exe rand.php
picking 10000 random numbers...
a picked 52 times
b picked 198 times
c picked 378 times
d picked 2655 times
e picked 543 times
f picked 761 times
g picked 5413 times

使用此示例运行相同的代码:

// samples with even weight
$samples = array(
   'a' => 0.1,
   'b' => 0.1,
   'c' => 0.1,
   'd' => 0.1
);

生成以下结果:

> php.exe rand.php
picking 10000 random numbers...
a picked 2520 times
b picked 2585 times
c picked 2511 times
d picked 2384 times
 类似资料:
  • 问题内容: 我想生成一组x个唯一的随机数,并在Python中对其进行排序。例如:range(1000,10000)x = 100 我想出了导入随机数并使用random.randrange方法,然后循环获取100个随机数,最后对它们进行排序。 但是,我不知道如何获得唯一的数字(这样就不会重复)-我应该验证每个循环吗?还是还有其他更简单的方法呢?我应该如何对它们进行排序? 问题答案: 采用 排序部分很

  • 问题内容: 我有一个字节数组,固定长度为4。 我需要将每个字节设置为随机字节。如何以最有效的方式这样做?就我而言,这些方法没有提供随机字节功能。 也许有一种内置的方式,还是我应该生成一个随机字符串并将其转换为字节数组? 问题答案: 包兰特 func Read 读取从默认源生成len(p)个随机字节,并将它们写入p。它总是返回len(p)和nil错误。 f unc(* Rand)读 读取生成len(

  • 本文向大家介绍如何生成一个随机数?相关面试题,主要包含被问及如何生成一个随机数?时的应答技巧和注意事项,需要的朋友参考一下  

  • 问题内容: 最重要的答案是建议使用switch语句来完成这项工作。但是,如果我要考虑的情况很多,那么代码看起来就很笨拙。我有一个巨大的switch语句,在每种情况下都一遍又一遍地重复非常相似的代码。 当您要考虑的概率很大时,是否有更好,更干净的方法来选择具有一定概率的随机数?(例如〜30) 问题答案: 这是一个Swift实现,受各种答案的影响很大,这些答案会生成具有给定(数字)分布的随机数 对于

  • 第一次在StackOverflow。我希望有人能帮我搜索一个算法。 我需要在给定的范围内生成N个随机数,求和到给定的和! null 可以生成N个常数和的数,解模,像这样:生成和是常数的随机数,但我不能用范围来完成。 或者通过产生N个随机值,将它们求和,然后将常数和除以随机和,然后将每个随机数乘以这个商,就像这里提出的那样。 我不能采用这些解决方案的主要问题是,我的每个随机值都有不同的范围,我需要这

  • 我有一个脚本,当加入时随机生成一个房间id。我想通过点击一个按钮复制那个ID。这将是一个简单的工作输入元素,然而,我不知道如何目标随机ID编辑和操作它。我怎么能那么做? null null 加入房间时已生成房间ID。我只需要把它拷贝到剪贴板上。添加“createroom”代码。