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

PHP:如何随机选择最大概率值?

凌修伟
2023-03-14

我有下面的数组

    $a = [
      149 => 55,
      130 => 10,
      131 => 5,
      132 => 5,
      133 => 10,
      134 => 10,
      135 => 5
    ];

   $rand = rand (0,(count($a)-1));

   echo array_values($a)[$rand];

这将给出主要结果为5,10,而不是55

总价值是100%概率。数值可以是十进制,也可以是55.55、10.10等,但总的来说是100%

我已经跟踪https://www.geeksforgeeks.org/how-to-get-random-value-out-of-an-array-in-php/

但这并没有给出预期的完美结果。

所以哪个概率最高应该主要随机选择。

所以结果可以是这样的:55,55,10,10,10,55,5,等等。。

我发现了一些有用的链接,可以在PHP中按权重生成随机结果?其中概率=重量

共有3个答案

沙星波
2023-03-14

据我所知,无论数组中出现多少次较小的数字,您都希望更高的数字在rand方法中出现得更频繁。你首先需要你的阵列。

随机加权和是一种简单的随机加权方法,但你可以通过加权和来更自由地控制权重。

$a = [
      149 => 55,
      130 => 10,
      131 => 5,
      132 => 5,
      133 => 10,
      134 => 10,
      135 => 5
    ];

$val_arr = array_unique(array_values($a));

function rand_by_sum($arr, $power=1){
        $sum = 0;
        $f_val = function($f)use($power){
                return pow($f, $power);
        };
        foreach($arr as $f){
                $sum += $f_val($f);
        }
        $rand = mt_rand(0, $sum);

        $tmp_sum = 0;
        foreach($arr as $f){
                $tmp_sum += $f_val($f);
                if($tmp_sum >= $rand) return $f;
        }
}

for($i=0; $i< 10; $i++){
        echo rand_by_sum($val_arr, $argv[1]) . " ";
}

echo "\n";

这里有一些不同功率的测试结果

php test.php 0.5
55 5 10 55 5 55 55 5 55 55 

php test.php 2
55 55 10 55 55 55 55 55 55 55 

php test.php 1
55 10 55 55 55 55 55 55 55 10

要获得值,将数组还原为55=

贺季
2023-03-14

这是一个类似于GA中轮盘赌轮选择的实现。答案的一个版本是EReload,但限制在总和而不是100。

    $a = [
      149 => 55,
      130 => 10,
      131 => 5,
      132 => 5,
      133 => 10,
      134 => 10,
      135 => 5
    ];

   echo randSelect($a);

   function randSelect($a) {
        $values = array_values($a);
        $sum = array_sum($values);
        $rand = (rand(0,1000)/1000) * $sum;
        $partialSum = 0;

        for ($i=0; $i < count($values); $i++) {
            $partialSum += $values[$i];
            if($partialSum >= $rand){
                return $values[$i];
                // incase you are using something like array_count_values and are actually looking for the keys
                // return array_keys($a)[$i];
            }
        }
   }
危晨
2023-03-14

现在,您的阵列是:-

55, 10, 5, 5, 10, 10, 5

现在,您应该生成一个介于[01100]之间的随机数,我们称之为r

  • 现在,如果r位于[0,55)之间,则选择值55。
  • 否则,如果r位于[55, 55 10 = 65)之间,则选择值10。
  • 否则,如果r位于[65, 65 5 = 70)之间,则选择值5。
  • 否则,如果r位于[70, 70 5 = 75)之间,则选择值5。
  • 否则,如果r位于[75, 75 10 = 85)之间,则选择值10。
  • 否则,如果r位于[85, 85 10 = 95)之间,则选择值10。
  • 否则,如果r位于[95, 95 5 = 100)之间,则选择值5。

我相信你会有这个想法...

因此,对于一般情况,如果您有一个名为“arr”的数组,这是伪代码:-

function SELECTPROB()
{
    $r = generateRandomNumber(0, 100);    //function to generate random number between 0 and 100, (100 exclusive)
    $sum = 0;
    foreach($arr as $i)
    {
        if($r >= $sum && $r < $sum + $i)
        {
            return $i
        }
        $sum = $sum + $i
    }
    return -1    //Should technically never reach upto this, but it can if your probability's sum is not 100
}
 类似资料:
  • 问题内容: 如何根据分配给每一行的概率机会从数据库中选择随机行。 例子: 如何根据必须选择的可能性来选择随机的品牌名称及其值。 和可以结合使用吗?如果是这样,最好的方法是什么? 问题答案: 您可以通过使用然后再使用累积和来执行此操作。假设它们的总和为100%: 笔记: 在子查询中被调用一次以初始化变量。多次调用是不可取的。 随机数极有可能恰好位于两个值之间的边界上。的任意选择1。 通过在时停止子查

  • 我想知道(例如在Java中)在特定范围内生成随机数的最佳方法是什么,其中每个数都有一定的发生概率? e. g. 从[1;3]中生成概率如下的随机整数: P(1)=0.2 P(2)=0.3 P(3)=0.5 现在,我正在考虑在[0;100]范围内生成一个随机整数的方法,并执行以下操作: 如果在[0; 20]以内--

  • 我正在构建一个游戏,我想在到之间选择一个随机数,我想让选择一个更高的数字的几率更低。 所以我问了这个问题,根据amit的回答,我写了这样一句话: 输出我在10000次跑步中选择每个数字的次数。 问题是,无论我选择的值是多少,我总是得到相同的输出。 我需要找到一种方法来修复这个算法,以便将影响拾取两个不同值之间的机会比率,而主要思想将保持不变:拾取更高的值将更难。

  • 问题内容: 这是我在数据库中查询一些单词的方法 我正在使用mysql,我想获得符合条件的随机行,我在查询中使用rand()的顺序。 我发现这个类似的问题基本上表明,由于在理论中不支持ORDER BY RAND,因此可以将主键随机化。但是,在我的情况下无法做到这一点,因为我有一个搜索条件和一个where子句,因此并非每个主键都可以满足该条件。 我还找到了一个代码段,建议您使用OFFSET来随机化行,

  • 让我们假设我有一个这样的结构化数组: 我将这个结构称为“categories”,所以,我在这个数组中有六个类别。我的目标是根据一个类别随机挑选一个产品。 我想做一个基于速率的类别选择,据我所知,我必须计算这个类别在数组中代表多少百分比,例如: 这会给我类似的东西: 好的,现在我要做一个简单的算法,根据这些比率得到类别;我想我现在需要在范围之间选择一个随机数,并制作一些“切片”,例如: 如果随机数介

  • 问题内容: 我想知道在特定范围内生成随机数的最佳方法(例如在Java中)是什么,而每个范围内的每个数字都有一定的发生概率? 例如 从[1; 3]内产生随机整数,并具有以下概率: P(1)= 0.2 P(2)= 0.3 P(3)= 0.5 现在,我正在考虑在[0; 100]内生成随机整数并执行以下操作的方法: 如果它在[0; 20]之内->我得到我的随机数1。 如果它在[21; 50]之内->我得到