PHP随机值可能来自5个项目,每个项目有多个项目


PHP random value from a possible 5 items with multiple items for each

我会尽力解释这一点。我需要根据每个项目中剩余的项目数量生成一个随机值(颜色)。

假设我有5种颜色,每种颜色有10个可用点:

Red = 10
Blue = 10
Green = 10
Yellow = 10
Black = 10

我想得到第一个随机的颜色,每种颜色都有相同的机会,因为它们都有10个斑点。然后,如果选择的第一个值是红色,则列表将看起来像

Red = 9
Blue = 10
Green = 10
Yellow = 10
Black = 10

然后,下一个随机值将使红色的权重略低,因为其他颜色中可用的斑点更高。假设红色再次被选中,那么列表将看起来像:

Red = 8
Blue = 10
Green = 10
Yellow = 10
Black = 10

因此,下一轮比赛将使瑞德的体重更低。

基本上,我希望每个点都有平等的机会被平等地选中,但要均匀地分配点(不按顺序排列)。

颜色可以大于或小于5,可用的斑点可以多达1000个。数据将被存储在DB中,但每秒可能有多个点请求,因此关于如何存储该数据的任何建议也将受到赞赏。一旦请求了一个点,它就会从颜色组中删除。

非常感谢!

由于您想在数据库中存储点,因此我不得不采用其他解决方案之外的另一种方法。

为了对其进行建模,使多个线程可以使用一种可用的颜色,您还可以有一个斑点表,将它们的颜色指示为集合或外键,以及一个具有唯一密钥和默认NULL的租约id。

您可以通过首先更新尚未使用租约id(uuid)租用的随机行来选择随机元素。从那时起,其他请求无法再选择该请求,您可以通过租约id进行选择查询,以了解它的颜色。这将确保不会出现竞争条件,并且您可以通过基于行的锁定同时为多个客户端提供服务。

有了10000个点,你可以存储一种颜色和一个租赁id,所以它将小于80kB。整个表将始终处于缓存中。

您可以将项目视为权重,然后选择一个随机值并将其与权重进行比较。遍历列表并从随机值中减去权重,直到它小于列表概率。在下一次迭代中,当项目被使用时,概率会发生变化,直到它为空。

   x = random([0.0, 1.0])
   for i in 0..n
       if x < probabilities[i]
        choose(i)
         break
       else
         x -= probabilities[i]
     end
    end

您可以尝试这样的方法。假设你有一个像你提到的数组,数据来自数据库:

red   => 100
green => 200
blue  =>  50

将所有组合颜色的值相加(在这种情况下为350)。选择一个介于1和1之间的随机值。

$randValue = rand(1, 350);

然后使用循环逐渐减去颜色的值,直到剩下0或负数:

foreach ($colors as $key => $value) {
    $randValue = $randValue - $value;
    if ($randValue < 1) {
        $pickedColor = $key;
        // and substract 1 from this color in the DB
        break;
    }
}

所以,在这种情况下,如果$randValue是124,你会得到绿色。