Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何创建平均分布的三人小组?_Php_Mysql - Fatal编程技术网

Php 如何创建平均分布的三人小组?

Php 如何创建平均分布的三人小组?,php,mysql,Php,Mysql,对于一个网站应用程序,我需要形成三个随机组。用户自己不能给自己评分(因此不能成为组的一部分)。将始终至少有4个用户 例如,如果有5个用户,我将有一个这样的数组:array(0,1,2,3,4),我希望输出是(其中键是用户,数据是3的组) 请注意,该用户从不在该组中,并且每个用户都被精确分配了3次 您不能简单地将用户随机选择到组中,因为它可能被分配3次以上,并强制某些组中的用户数少于3个 我希望我恰当地解释了这个问题,有人能提供帮助 下面是一些将三个随机数放入字典中的代码,对于[0,1,2,3]来

对于一个网站应用程序,我需要形成三个随机组。用户自己不能给自己评分(因此不能成为组的一部分)。将始终至少有4个用户

例如,如果有5个用户,我将有一个这样的数组:array(0,1,2,3,4),我希望输出是(其中键是用户,数据是3的组)

请注意,该用户从不在该组中,并且每个用户都被精确分配了3次

您不能简单地将用户随机选择到组中,因为它可能被分配3次以上,并强制某些组中的用户数少于3个

我希望我恰当地解释了这个问题,有人能提供帮助

下面是一些将三个随机数放入字典中的代码,对于[0,1,2,3]来说效果很好,但是对于任何较大的数字(很可能)都会失败,因为这些数字的分布不均匀(并且将永远在while循环中,因为没有可能的数字了)

$rows=范围(0,3);
$array\u size=计数($rows);
$peers_array=array();
$number\u count=数组填充(0,$array\u size,0);
foreach($index=>$row的行){
$randomNumbers=Array();
对于($x=0;$x<3;++$x){
$randomNumber=rand(0,$array\u size-1);
而($randomNumber==$index或在数组中($randomNumber,$randomNumbers)或$number\U count[$randomNumber]>2)
$randomNumber=rand(0,$array\u size-1);
$number_count[$randomNumber]++;
$randomNumber[]=$randomNumber;
}
$peers_数组[$index]=$randomNumber;
}
打印\u R($peers\u array);

我认为
数组\u pop
是一种很好的方法,它可以很好地解决问题的第一部分,很容易获得当前项目,并确保它在下一部分不可用,但是最后你不得不跟踪太多移动的部分

最后,使用
array_diff
从原始数组中删除当前行

$rows = range(0,15);
$results = array();
foreach ($rows as $row) {
    $others = array_diff($rows,array($row));
    shuffle($others);
    $results[$row] = array_slice(array_values($others),0,3);
}
var_dump($results);
结果:

array (size=16)
  0 => 
    array (size=3)
      0 => int 9
      1 => int 1
      2 => int 10
  1 => 
    array (size=3)
      0 => int 10
      1 => int 11
      2 => int 14
  2 => 
    array (size=3)
      0 => int 3
      1 => int 15
      2 => int 14
  3 => 
    array (size=3)
      0 => int 9
      1 => int 4
      2 => int 1
      etc...
我认为:(概括地说)

函数getUsers($users,$groups\u of){ $result=array(); 对于($i=0;$i<$users;$i++){ $usernums=array(); 而(count($usernums)<$groups_of){ $randomNumber=rand(0,$users-1); if($i!=$randomNumber&&!在数组中($randomNumber,$usernums)){ $usernums[]=$randomNumber; } } $result[$i]=$usernums; } 返回$result; } $users=5; $groups\u of=3; 打印(getUsers($users,$groups of));
好的,我想出了自己的解决方案。这需要一点思考,但多亏了建议,我才想出了这个解决方案:

首先,它生成一个从0到用户数-1的范围(例如,对于5,它将给出[0,1,2,3,4]),然后每次之后它将列表1移动(例如[0,1,2,3,4]变为[4,0,1,2,3]),然后它将数组给定索引处的每个元素放入一个组中(因此,如果我只需要2个组,它将给出0[0,4]1:[0,1]2:[2,1]等等。然后在用户数量和组大小之间切换顺序,不要问,相信我。这保证了所有数字出现的次数相等,但仍然会随机化顺序

以下几行实现了这一点:

function getUsers($user_num, $groups_of){
    $index_list = range(0,$user_num-1);
    $random_indexes = range(0,$user_num-1);
    shuffle($random_indexes);

    $groups = array();
    foreach($index_list as $user_num)
        $groups[] = array($random_indexes[$user_num]);

    for($i = 0; $i<($groups_of-1); ++$i){
        array_unshift($index_list, array_pop($index_list)); //puts the last element first

        foreach($index_list as $index => $user_num)
            $groups[$index][] = $random_indexes[$user_num];
    }

    $shift_number = rand(1, ($len_users-$groups_of));
    for($i = 0; $i<$shift_number; ++$i)
        array_unshift($groups, array_pop($groups));

    return $groups
}
函数getUsers($user\u num,$groups\u of){ $index\u list=范围(0,$user\u num-1); $random_index=范围(0,$user_num-1); 洗牌($random_索引); $groups=array(); foreach($index\u列表为$user\u num) $groups[]=数组($random_index[$user_num]); 对于($i=0;$i$user\u num) $groups[$index][]=$random_index[$user_num]; } $shift_number=rand(1,($len_用户-$groups_of));
对于($i=0;$i为原始问题添加了一些代码,但它没有跟踪条目的数量,因为我想不出一种方法可以在完美分配数字的同时做到这一点。我认为这不是OP想要的。他们想要3个组,而不管初始数组的大小。@serakfalcon谢谢,为g添加了一个数组拼接设置前3个元素。这不起作用,因为每个数字都会出现4次而不是3次,一组中的最大值也应该是3。也许我解释得不够清楚。可能不是最有效的方法,PHP会在shuffle和diff中对未使用的元素做额外的工作,但也不是很详细。我不能对此投反对票这是因为这是一个很好的努力,但我也无法改进它,因为它不能完全满足简要要求-除非结果集不完整!?!这与我的函数所做的几乎相同,只是它没有跟踪用户在组中出现的时间。因此,例如,用户4可能会出现超过组的大小。
array (size=16)
  0 => 
    array (size=3)
      0 => int 9
      1 => int 1
      2 => int 10
  1 => 
    array (size=3)
      0 => int 10
      1 => int 11
      2 => int 14
  2 => 
    array (size=3)
      0 => int 3
      1 => int 15
      2 => int 14
  3 => 
    array (size=3)
      0 => int 9
      1 => int 4
      2 => int 1
      etc...
function getUsers($users,$groups_of){
    $result = array();
    for($i = 0; $i < $users; $i++){
        $usernums = array();
        while(count($usernums) < $groups_of){ 
            $randomNumber = rand(0, $users-1);
            if($i != $randomNumber && !in_array($randomNumber, $usernums)){
                $usernums[] = $randomNumber;
            }
        }
        $result[$i] = $usernums;
    }
    return $result;
}


$users = 5;
$groups_of = 3;
print_r(getUsers($users,$groups_of));
function getUsers($user_num, $groups_of){
    $index_list = range(0,$user_num-1);
    $random_indexes = range(0,$user_num-1);
    shuffle($random_indexes);

    $groups = array();
    foreach($index_list as $user_num)
        $groups[] = array($random_indexes[$user_num]);

    for($i = 0; $i<($groups_of-1); ++$i){
        array_unshift($index_list, array_pop($index_list)); //puts the last element first

        foreach($index_list as $index => $user_num)
            $groups[$index][] = $random_indexes[$user_num];
    }

    $shift_number = rand(1, ($len_users-$groups_of));
    for($i = 0; $i<$shift_number; ++$i)
        array_unshift($groups, array_pop($groups));

    return $groups
}