Example #1
0
function ComputeAssignment(&$tpl, $db, $maxReviewers)
{
    // Decompose the blocks of the template
    $tpl->set_block("content", "MEMBER_DETAIL", "MEMBERS");
    $tpl->set_block("content", "PAPER_DETAIL", "PAPERS");
    $tpl->set_block("content", "GROUP_DETAIL", "GROUP");
    $tpl->set_block("PAPER_DETAIL", "ASSIGNMENT_DETAIL", "ASSIGNMENTS");
    // This function might take a while to execute...
    ini_set("max_execution_time", "900");
    // 15 mns, should be enough...
    $tpl->set_var("MEMBERS", "");
    $tpl->set_var("PAPERS", "");
    $tpl->set_var("RESULTS", "");
    $tpl->set_var("ASSIGNMENTS", "");
    // Get global parameters
    $nbReviewers = Config::countAllReviewers();
    $nbPapers = Config::countAllPapers();
    $refPerPap = $maxReviewers;
    // How many papers for each referee ?
    $papRef = $nbPapers * $refPerPap;
    $papForRef = floor($papRef / $nbReviewers) + 1;
    // Templates assignment
    $tpl->set_var("NUMBER_PAPERS", $nbPapers);
    $tpl->set_var("NUMBER_REVIEWERS", $nbReviewers);
    $tpl->set_var("REVIEWERS_PAPERS", $refPerPap);
    $tpl->set_var("MAX_PAPERS_REVIEWER", $papForRef);
    if (isset($_REQUEST['idMin'])) {
        // A group must be computed
        $idMin = $_REQUEST['idMin'];
        $idMax = $_REQUEST['idMax'];
        $nbGroups = 1;
    } else {
        if ($nbPapers > MAX_PAPERS_IN_ROUND) {
            $tpl->set_file("TxtAssignmentGroups", "assigngroup.xml");
            $tpl->set_block("TxtAssignmentGroups", "GROUP_DETAIL", "GROUPS");
            $tpl->set_var("GROUPS", "");
            $tpl->set_var("MAX_PAPERS_IN_ROUND", MAX_PAPERS_IN_ROUND);
            // How many groups do we create?
            $nbGroups = $nbPapers / MAX_PAPERS_IN_ROUND + 1;
            $nb_papers_per_group = $nbPapers / $nbGroups;
            // Compute the groups
            $rPapers = $db->execRequete("SELECT * FROM Paper ORDER BY id");
            $iPaper = 0;
            $idMin = $idMax = -1;
            $iGroup = 1;
            $groups = array();
            while ($paper = $db->objetSuivant($rPapers)) {
                if ($idMin == -1) {
                    $idMin = $paper->id;
                }
                if ($paper->id > $idMax) {
                    $idMax = $paper->id;
                }
                $iPaper++;
                if ($iPaper > $nb_papers_per_group) {
                    // Create a group
                    $groups[$iGroup++] = array("idMin" => $idMin, "idMax" => $idMax);
                    $idMin = $idMax = -1;
                    $iPaper = 0;
                }
            }
            // Create the last group
            $groups[$iGroup] = array("idMin" => $idMin, "idMax" => $idMax);
            foreach ($groups as $key => $val) {
                $idMin = $val['idMin'];
                $idMax = $val['idMax'];
                $tpl->set_var("GROUP_ID", "{$key}");
                $tpl->set_var("ID_MIN", $idMin);
                $tpl->set_var("ID_MAX", $idMax);
                $tpl->append("GROUPS", "GROUP_DETAIL");
            }
            $tpl->assign("content", "assigngroup");
            return;
        } else {
            $nbGroups = 1;
            $nb_papers_per_group = $nbPapers;
        }
    }
    /* Not useful if one priviledges the number of reviewers for each paper
       $papRef = $maxReviewers * $nbPapers;
       $papForRef = floor((float) $papRef / (float) $
       if ($papRef % $nbReviewers != 0) floor($papForRef++);
       */
    // Create two arrays, one for members,  one for papers
    $members = $papers = array();
    $qMembers = "SELECT * FROM User WHERE roles LIKE '%R%' ORDER BY last_name";
    $rMembers = $db->execRequete($qMembers);
    $iMember = 1;
    while ($member = $db->objetSuivant($rMembers)) {
        $members[$iMember++] = $member->id;
    }
    $nbReviewers = $iMember - 1;
    if (isset($idMin)) {
        $qPapers = "SELECT * FROM Paper WHERE id BETWEEN {$idMin} AND {$idMax} ORDER BY id";
    } else {
        $qPapers = "SELECT * FROM Paper ORDER BY id";
    }
    $rPapers = $db->execRequete($qPapers);
    $iPaper = 1;
    while ($paper = $db->objetSuivant($rPapers)) {
        $papers[$iPaper++] = $paper->id;
    }
    $nbPapers = $iPaper - 1;
    // OK, let's do the assignment
    if ($nbPapers > $nbReviewers) {
        $n = $nbPapers;
    } else {
        $n = $nbReviewers;
    }
    /*  echo "Nbpapers = $nbPapers Nb rev.=$nbReviewers N=$n<br>";
       return;
       */
    // Create the matrix
    $weight = array();
    reset($papers);
    while (list($iPaper, $idPaper) = each($papers)) {
        reset($members);
        while (list($iRef, $id_user) = each($members)) {
            $weight[$iRef][$iPaper] = GetRatingValue($idPaper, $id_user, $db);
        }
        // Complete to obtain a square matrix
        if ($nbReviewers < $n) {
            for ($i = $nbReviewers + 1; $i <= $n; $i++) {
                $weight[$i][$iPaper] = 0;
            }
        }
    }
    // Complete to obtain a square matrix if nbPapers < nbReviewers
    if ($nbPapers < $n) {
        for ($i = $nbPapers + 1; $i <= $n; $i++) {
            reset($members);
            while (list($iRef, $email) = each($members)) {
                $weight[$iRef][$i] = 0;
            }
        }
    }
    // End of init ****
    // Initialize the arrays
    $assignedPapers = $chosenPapers = $Rmate = $Lmate = $choice = array();
    for ($i = 1; $i <= $nbPapers; $i++) {
        $chosenPapers[$i] = 0;
    }
    for ($i = 1; $i <= $nbReviewers; $i++) {
        $assignedPapers[$i] = 0;
        for ($j = 1; $j <= $nbPapers; $j++) {
            $choice[$i][$j] = 0;
        }
    }
    $wsum = 1;
    // dummy for first iteration
    for ($i = 1; $wsum > 0; $i++) {
        for ($j = 1; $j <= $n; $j++) {
            $Rmate[$j] = $Lmate[$j] = 0;
        }
        // Compute the matching for the current ballot
        matching($n, $Lmate, $Rmate, $weight);
        // Make the assignment - Remove choices already made
        takeout($nbReviewers, $nbPapers, $Lmate, $weight, $choice, $chosenPapers, $assignedPapers, $wsum, $maxReviewers, $papForRef);
        // if ($i >= $maxReviewers) break;
    }
    // Insert results in the DB
    $db->execRequete("DELETE FROM Assignment");
    reset($papers);
    while (list($iPaper, $idPaper) = each($papers)) {
        $weightPaper = 0;
        reset($members);
        $tabMails = array();
        while (list($iRef, $id_user) = each($members)) {
            $weight = $choice[$iRef][$iPaper];
            if ($weight != 0) {
                $tabMails[] = $id_user;
                $query = "INSERT INTO Assignment(idPaper, id_user, weight)" . "VALUES ('{$idPaper}', '{$id_user}', '{$weight}')";
                $db->execRequete($query);
            }
        }
        // Insert the assignment in the Review table
        // SQLReview ($idPaper, $tabMails, $db);
    }
    // Report the result
    ReportAssignment($tpl, $members, $papers, $choice, $db);
    if (isset($idMin)) {
        $tpl->set_var("ID_MIN", $idMin);
        $tpl->set_var("ID_MAX", $idMax);
        $tpl->parse("GROUP", "GROUP_DETAIL");
    } else {
        $tpl->set_var("GROUP", "");
    }
}