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