php循环中的伪随机分布

ulydmbyx  于 2023-04-04  发布在  PHP
关注(0)|答案(2)|浏览(109)

我有一些代码,可以根据来自不同数组的先验参数生成一个随机输出
数据设置:

$persons = array("Old", "Young", "Child");
$moods = array("neutral", "happy", "sad");
$newarray= "";

shuffle($persons );
$persons2 = array_merge(...array_fill(1, 92, $persons ));
$persons2 = $array = array_slice($persons2, 1, 30);

shuffle($moods);
$moods2 = array_merge(...array_fill(1, 92, $moods));
$moods2 = $array = array_slice($moods2, 1, 30);

所需的输出是一个if循环,它生成由等量的old、young和child对象组成的字符串,这些对象中的每一个都是等量的中性、快乐和悲伤对象,类似于

for ($x = 0; $x <= 30; $x++) {

$mood = $moods2[$x % (count($moods2))];
$person = $persons2 [$x % (count($persons2))];
$newarray .= "|".$person.",".$mood."|";

  }

这段代码的问题是,它不能确保情绪“快乐”、“悲伤”、“中性”与人物类别“年老”、“年轻”、“儿童”均匀地组合。

$newarray= "|Old,happy||Old,sad||Old,netrual||Young,happy||Young,sad||Young,netrual||Child,happy||Child,sad||Child,neutral|";

使得存在30次迭代并且可能的人/情绪组合同样频繁地出现。
并不是说我也希望最终的输出是随机排序的,并且即使改变for循环的迭代次数,代码也应该工作。

uujelgoq

uujelgoq1#

填充笛卡尔积,然后根据需要循环多次,并使用循环索引访问(通过模数计算)获取混洗数组中的下一个元素。
代码:(Demo

$persons = ["Old", "Young", "Child"];
$moods = ["neutral", "happy", "sad"];
$size = 30;

$cartesianStrings = [];
foreach($persons as $p) {
    foreach($moods as $m) {
        $cartesianStrings[] = $p . ' ' . $m;
    }
}

shuffle($cartesianStrings);
$cartesianSize = count($cartesianStrings);
for ($x = 0; $x <= $size; ++$x) {
    $result[] = '|' . $cartesianStrings[$x % $cartesianSize] . '|';
}
shuffle($result);
echo implode($result);
ugmeyewa

ugmeyewa2#

你要做的是创建一个所有可能的输入排列的集合,然后用排列的集合填充一个所需大小的数组,然后 Shuffle 。

<?php

$person = ['Old', 'Young', 'Child'];
$moods = ['neutral', 'happy', 'sad'];

// Create a buffer for our set of combinations
$cartesianProduct = [];

// Nested loop to create the total set of combinations
foreach($person as $currPerson)
{
    foreach($moods as $currMood)
    {
        // Create string representation of the combination
        $cartesianProduct[] = $currPerson.' '.$currMood;
    }
}

// Desired size of output array
$limit = 30;

// Buffer for the final output
$output = [];

// Start at a random point and keep track of where we are in the set of possible combinations
$cartIndex = array_rand($cartesianProduct);

// Loop until we have the desired buffer size
while (sizeof($output) < $limit)
{
    // Add the current input to the output and increment the input index
    $output[] = $cartesianProduct[$cartIndex++];

    // If we have reached the end of the input buffer, reset to zero
    if ($cartIndex == sizeof($cartesianProduct))
    {
        $cartIndex = 0;
    }
}

// Randomize the output buffer
shuffle($output);

// Let's look at the results...
print_r($output);

您可以使用一个类来创建笛卡尔积,以一种更通用和更可重用的方式(并支持任意数量的输入集,而不仅仅是两个)来实现这一点。

<?php

class Cartesian
{
    public static function build($set)
    {
        if (!$set) {
            return [[]];
        }

        $subset = array_shift($set);
        $cartesianSubset = self::build($set);

        $result = [];
        foreach ($subset as $value)
        {
            foreach ($cartesianSubset as $p)
            {
                array_unshift($p, $value);
                $result[] = $p;
            }
        }

        return $result;
    }
}

// Input set - can by any number of "rows"
$input = [
    ['Old', 'Young', 'Child'],
    ['neutral', 'happy', 'sad']
];

// Build our total set of permutations
$cartesianProduct = Cartesian::build($input);

// Desired size of output array
$limit = 30;

// Buffer for the final output
$output = [];

// Start at a random point and keep track of where we are in the set of possible combinations
$cartIndex = array_rand($cartesianProduct);

// Loop until we have the desired buffer size
while (sizeof($output) < $limit)
{
    // Get the current input and increment the input index
    $currProduct = $cartesianProduct[$cartIndex++];
    
    // Add a string representation of the current entry to the output 
    $output[] = $currProduct[0].' '.$currProduct[1];

    // If we have reached the end of the input buffer, reset to zero
    if ($cartIndex == sizeof($cartesianProduct))
    {
        $cartIndex = 0;
    }
}

// Randomize the output buffer
shuffle($output);

// Let's look at the results...
print_r($output);

相关问题