首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >随机而均匀地分组N个人?(姓名及性别)

随机而均匀地分组N个人?(姓名及性别)
EN

Stack Overflow用户
提问于 2017-11-19 18:17:20
回答 2查看 95关注 0票数 1

因此,我试图创建一个算法(?)指派某人到教室。每个班级的要求是:

  1. 至少有30人,最多45人
  2. 人的名字不会是“同母”(例如:1-3级的人名都以字母"A“开头,而4-5级则是"B”等)。
  3. 性别分布也是均匀的
  4. 如果该类已满,则其余的人将被移至等候名单。

我的数据有列唯一的ID、名称和性别。我对这种东西还不熟悉(算法?)所以我甚至不知道从哪里开始。有可能吗?我从哪里开始?我使用的是PHP,我的数据在MySQL数据库中

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-19 19:12:41

第一步

您需要从DateBase (所有人)获得数据

代码语言:javascript
复制
$host = '***';
$user = '***'';
$password = '***'';
$database = '***'';

$link = mysqli_connect($host, $user, $password, $database) or die("Error" . mysqli_error($link));
$query = "SELECT * FROM people";

$people = mysqli_query($link, $query) or die("Error" . mysqli_error($link));
mysqli_close($link);

第二步

将mysql_result转换为数组并对其进行洗牌。

代码语言:javascript
复制
$people = [];
foreach ($result as $person) {
    $people[] = $person;
}
shuffle($people);

第三步

有算法:

代码语言:javascript
复制
$count = count($people);
// Classes
$classes = [];
const MIN_SIZE = 30;
const MAX_SIZE = 45;


$maxSizeClass= $count / MIN_SIZE;
$minSizeClass= $count / MAX_SIZE;

$countClasses = max(ceil($minSizeClass), floor($maxSizeClass));
$currentCountClass = $count / $countClasses;

$tmpClass = [];
foreach ($people as $person) {
    if (count($tmpClass) < $currentCountClass) {
        $tmpClass[] = $person;
    } else {
        $classes[] = $tmpClass;
        $tmpClass = [];
    }
}

if (count($tmpClass) >= MIN_SIZE) {
    $classes[] = $tmpClass;
    $tmpClass = [];
}

foreach ($tmpClass as $index => $person) {
    foreach ($classes as &$class) {
        if (count($class) < MAX_SIZE) {
            $class[] = $person;
            // be careful, PHP7 is OK
            unset($tmpClass[$index]);
            continue 2;
        }
    }
}

// persons awaiting distribution
$waitingQueue = $tmpClass;

第四步

结果是:

$waitingQueue -等待分发的人员

$classes -有人员的班级

票数 0
EN

Stack Overflow用户

发布于 2017-11-20 00:16:22

代码语言:javascript
复制
$letters = array('a','b',....,'y','z');
foreach($letters as $letter){
    $sql['male'] = "SELECT * FROM people_table WHERE person_name LIKE '".$letter."%' AND person_gender = 'male' ORDER BY person_name";
    $sql['female'] = "SELECT * FROM people_table WHERE person_name LIKE '".$letter."%' AND person_gender = 'female' ORDER BY person_name";
    foreach($sql as $key => $query){
        $results[$key] = $connection->query($query);
        for($i = 0; $i < $results[$key]->num_rows; $i++){
            $people[$letter][$key][] = results->fetch_array(MYSQLI_ASSOC);
        }
    }
}

这是按性别分列的名单.现在我们可以把它循环起来,一对一地插入一个男人和一个女人。如果对列表的count();小于30,人们等待的时间越长。如果大于44 (因为成对不可能有45人,当然,如果我不理解这个问题),那么将这44保存在一个类数组$class[$letter]中,您可以通过每个字母看到所有的类。要了解您总共拥有多少类,可以使用count($class);,或者如果您想知道一个特定字母的多少类,您可以使用count($class[$letter]);

您可以在foreach数组中重做其他$letters,也可以将循环放在上面的foreach中来创建类数组。决赛时,在foreach($letters as $letter){}内部:

代码语言:javascript
复制
if( !(count($people[$letter][$key]) < 15 OR count($people[$letter][$key]) < 15) ){
    $she = count($people[$letter]['female'];
    $he = count($people[$letter]['male'];
    if($she < $he){
        for($i = 0; $i < 2*count($she); $i++){
            $class[$letter][$i] = $people[$letter]['female'][$i];
            $class[$letter][$i+1] = $people[$letter]['male'][$i];
            $i++;//Important to avoid replace values!
        }
    } else {
        for($i = 0; $i < 2*count($he); $i++){
            $class[$letter][$i] = $people[$letter]['female'][$i];
            $class[$letter][$i+1] = $people[$letter]['male'][$i];
            $i++;//Important to avoid replace values!
        }
}

在更大的if中,错误的布尔值意味着不能创建这个字母性别分布均匀的类。您可以再次循环使数组的一个条目中的每个类。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47380323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档