如何从数组中获取一个不那么随机的值?

时间:2015-02-05 11:22:00

标签: php arrays random

想法

在工作中,我们有一项任务,没有人想做。所以我尝试制作一个脚本,从一个数组中随机选择一个人并显示他们的名字。但是,当我们有实习生时,我们希望他/她比其他人更频繁地出现。

请记住,这只是代码的一些愚蠢行为。

代码

<?php
if (!isset($_COOKIE['names'])) {
    // Prepare initial array
    $names = array(
        'John Doe' => 10,
        'Jane Doe' => 10,
        'Mike Doe' => 10,
        'Gina Doe' => 10,
        'Anne Doe' => 10,
        'George Doe' => 10,
        'Jack Doe' => 10,
    );

    // Create cookie
    setcookie('names', serialize($names), time()+28800);
}

$names = unserialize($_COOKIE['names']);

$randomArray = array();
foreach ($names as $name => $probability) {
    if ($probability > 1) {
        foreach (range(1, $probability) as $v) {
            $randomArray[] = $name;
        }
    } else {
        $names[$name] = 10;
    }
}

$selected = $randomArray[array_rand($randomArray)];
if (array_key_exists($selected, $names)) {
    if ($names[$selected] > 1) {
        $names[$selected]--;
    }
    setcookie('names', serialize($names), time()+28800);
    echo $selected;
}

通过查看此代码,我猜你会得到一般的想法。通过提高概率,人们的名字会更频繁出现。

问题

当概率达到1时,我将其设置为10.但不知何故,这感觉不对。我不是一个微积分的奇迹,但我的脑袋可以弄清楚这是不对的。而且,我写的那段代码根本没有效率。在我看来,循环太多了。

我想问的是,你要看看我的代码并告诉我它是什么,我做错了,我能做些什么来改进它。建议等也欢迎。

3 个答案:

答案 0 :(得分:2)

快速,简单/懒惰的方法是添加更多你想要的人的实例,以增加履行职责的机会:

$names = array(
    'John Doe',
    'Jane Doe',
    'Mike Doe',
    'Gina Doe',
    'Anne Doe',
    'George Doe',
    'Jack Doe',//intern - 50% of getting selected
    'Jack Doe',
    'Jack Doe',
    'Jack Doe',
    'Jack Doe',
    'Jack Doe',
);
var_dump(array_rand($names));

修改

因此,您的代码正在生成以上内容,并且您希望简化它:

$names = array(
    'John Doe' => 1,
    'Jane Doe' => 1,
    'Mike Doe' => 2,
    'Gina Doe' => 3,
    'Anne Doe' => 5,
    'George Doe' => 8,
    'Jack Doe' => 13,
);
$randomNames = array();
foreach($names as $name => $probability) {
    do {
        $randomNames[] = $name;
    } while (--$probability > 0);
}
var_dump($randomNames[array_rand($randomNames)]);

编辑2

我刚刚弄清楚了COOKIE正在做的事情。降低每个名字的概率:

session_start();
// instantiate array
$names = array(
    'John Doe' => 1,
    'Jane Doe' => 1,
    'Mike Doe' => 2,
    'Gina Doe' => 3,
    'Anne Doe' => 5,
    'George Doe' => 8,
    'Jack Doe' => 13,
);

// if array exists in session, use that
if(array_key_exists('names',$_SESSION)) {
    $names = unserialize($_SESSION['names']);
}

// Add each name x times where 'x' is the value of $probability
$randomNames = array();
foreach($names as $name => $probability) {
    do {
        $randomNames[] = $name;
    } while (--$probability > 0);
}

// reduce probability by one. If value is less than, or equal to, 0 then reset probability yo 10
$chosen = $randomNames[array_rand($randomNames)];
$names[$chosen]--;
if($names[$chosen] <= 0) {
    $names[$chosen] = 10;
}

// Save array into session for next run
$_SESSION['names'] = serialize($names);

var_dump($chosen,$names);

答案 1 :(得分:1)

我假设数组中的数字是概率的权重 - 即使你把它们都设置为10 ......

因此,要从数组中进行选择,您需要类似......

的内容
$weight_total = 0;
foreach ($names as $weight) 
  $weight_total += $weight;

$random_number = rand(1, $weight_total); // Random number between 1 and $weight_total

$running_total = 0;
foreach ($names as $name => $weight) {
  if ($random_number > $running_total && $random_number <= ($running_total + $weight)) {
     echo $name; 
     break;
  }
  $running_total += $weight;
}

然后将实习生的体重设定为高于其他人。

答案 2 :(得分:0)

我会选择一个随机数来确定它是“群组”还是“穷人实习生”,如果是“群组”,则另取一个随机来确定群组中的哪个成员。