【问题标题】:Creating not-so-random list from given array in PHP从 PHP 中的给定数组创建非随机列表
【发布时间】:2013-07-05 21:57:21
【问题描述】:

我需要生成 n ($size_of_list) 名称列表... 可能的成员在数组 ($names_list) 中给出,它给出了名称和该名称出现的机会。所以它是一个 40 个字符串和整数数组的数组:

$names_list = array (
                     0 => array ('name' => "Mike", 'frequency' => 8),
                     1 => array ('name' => "Jane", 'frequency' => 7),
                     2 => array ('name' => "Leopold", 'frequency' => 1),
                     3 => array ('name' => "George", 'frequency' => 5),
...
                     39 => array ('name' => "Mark", 'frequency' => 6)
                    )

$names_list[0] = array('name' => "Mike", 'frequency' => 8) 表示 $name="Mike" 的 $frequency(或机会)为 8,而 "Leopold" 的机会值为 1 - 出现的机会很小......

【问题讨论】:

  • 我的问题是这个数组可能有多大,好像它是相当大的可能的解决方案可能会遇到内存限制,另一个问题是什么是在第一个实例中生成这个数组?可能有更聪明的方法来解决这个问题
  • @Anigel 输入数组 $names_list 的大小始终为 40 个元素,但输出可高达 5-6.000 个元素...实际上我还有 5-6 个输入数组需要生成至少 4-5.000 个元素的测试数据库...
  • @Anigel 但我会将生成的值一一放入数据库中,因此大小无关紧要:)

标签: php list random


【解决方案1】:

我的想法是用新值 'rnd' 扩展数组,它表示 $frequency 和先前元素 rnd 的总和(其中第一个元素“rnd”是第一个元素的“频率”)

$names_list[0]['rnd'] = $names_list[0]['frequency'];
for ($i=1; $i<count($names_list); $i++)
    $names_list[$i]['rnd'] = $names_list[$i]['frequency'] + $names_list [$i-1]['rnd'];  

扩展数组看起来像这样:

$names_list = array (
                     0 => array ('name' => "Mike", 'frequency' => 8, 'rnd' => 8),
                     1 => array ('name' => "Jane", 'frequency' => 7, 'rnd' => 15),
                     2 => array ('name' => "Leopold", 'frequency' => 1, 'rnd' => 16),
                     3 => array ('name' => "George", 'frequency' => 5, 'rnd' => 21),
//... other elements
                     39 => array ('name' => "Mark", 'frequency' => 8, 'rnd' => $sum_of_all_frequencies)
                    )

然后将 $rand_max 设置为最后一个元素的值'rnd',然后通过 比较 $random 和所有 'rnd' 值...

$rand_max = $names_list[count($names_list)-1]['rnd'];

for ($i=1; $i<$size_of_list; $i++)
{
    $random = rand (1, $rand_max);
    $result = $names_list[0]['name'];
    foreach ($names_list as $key => $val)
        if ( ($random) > ($val['rnd']) )
            $result = $names_list[$key+1]['name'];

    $list[$i] = $result;
}

此解决方案有效,但我认为有更好(更智能)的方法...
我将不胜感激任何帮助/建议...

【讨论】:

    【解决方案2】:

    指定 $size_of_list 并最后检查 $result。这根据权重使用随机数。

    $result = array();
    
    $total = 0;
    foreach ($names_list as $row) {
        $total += $row['frequency'];
    }
    
    $max = mt_getrandmax();
    $pre_sum = $total / $max;
    
    for ($i = 0; $i < $size_of_list; ++$i) {
    
        $sum = $pre_sum * mt_rand(0, $max); // $sum = $total * (mt_rand(0, $max)/$max);
    
        foreach ($names_list as $row) {
            if (($sum -= $row['frequency']) < 0) {
                $result[] = $row['name'];
                break;
            }
        }
    }
    
    var_dump($result);
    

    【讨论】:

    • 谢谢,这是我计划做的第一件事,但不知道怎么做:)
    猜你喜欢
    • 1970-01-01
    • 2021-04-11
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多