function calculate_score()
{
    global $score_board;
    global $TOTAL_P_SCORE;
    global $score_P_ratio;
    $qCur = new SplPriorityQueue();
    $qExpire = new SplPriorityQueue();
    $total_p_score = $TOTAL_P_SCORE;
    $multiplier = 0.01;
    $qCur->setExtractFlags(SplPriorityQueue::EXTR_DATA);
    $qExpire->setExtractFlags(SplPriorityQueue::EXTR_DATA);
    foreach ($score_board as $k => $r) {
        ///// f_score
        if (IsValidScoreboardEntry($k)) {
            $score_board[$k]["func"] = $score_board[$k]["check_pattern"] * pow(0.9, $score_board[$k]["mem_error"]);
            if ($score_board[$k]["mem_heap"] > 0) {
                $score_board[$k]["func"] *= ($score_board[$k]["mem_heap"] - $score_board[$k]["heap_lost"]) / $score_board[$k]["mem_heap"];
            }
            if ($r["priority"] > 0) {
                $qCur->insert($k, $r["priority"]);
            }
        } else {
            $score_board[$k]["func"] = 0;
        }
        ////// init p_score
        $score_board[$k]["p_score"] = 0;
    }
    while ($qCur->valid() && $total_p_score > 0) {
        while ($qCur->valid()) {
            $idx = $qCur->extract();
            $s = $score_board[$idx]["priority"] * $multiplier;
            // alloted score in the scheduling cycle
            if ($s > 100 - $score_board[$idx]["p_score"]) {
                $s = 100 - $score_board[$idx]["p_score"];
            }
            $score_board[$idx]["p_score"] += $s;
            $total_p_score -= $s;
            if ($score_board[$idx]["p_score"] < 100) {
                $qExpire->insert($idx, $score_board[$idx]["priority"]);
            }
        }
        $qCur = $qExpire;
        $qExpire = new SplPriorityQueue();
        $qExpire->setExtractFlags(SplPriorityQueue::EXTR_DATA);
    }
    foreach ($score_board as $k => $r) {
        $score_board[$k]["score"] = 100 * $score_board[$k]["func"] * (1 - $score_P_ratio + $score_board[$k]["p_score"] * $score_P_ratio / 100);
    }
    ////////sort by score
    $tmp = array();
    foreach ($score_board as &$ma) {
        $tmp[] =& $ma["score"];
    }
    array_multisort($tmp, SORT_DESC, $score_board);
}
function calculate_score()
{
    global $score_board;
    global $TOTAL_P_SCORE;
    global $score_P_ratio;
    global $REMAINING_P_SCORE;
    global $LATE_SUBMISSION_PENALTY;
    global $tmDeadline;
    $qCur = new ScorePriorityQueue();
    $qExpire = new ScorePriorityQueue();
    $total_p_score = $TOTAL_P_SCORE;
    $multiplier = -1;
    $qCur->setExtractFlags(ScorePriorityQueue::EXTR_DATA);
    $qExpire->setExtractFlags(ScorePriorityQueue::EXTR_DATA);
    foreach ($score_board as $k => $r) {
        ///// f_score
        if (IsValidScoreboardEntry($k)) {
            //var_dump($score_board[$k]);
            $score_board[$k]["func"] = $score_board[$k]["check"] * pow(0.95, $score_board[$k]["m_error"]);
            if ($score_board[$k]["m_peak"] > 0) {
                $score_board[$k]["func"] *= ($score_board[$k]["m_peak"] - $score_board[$k]["heap_lost"]) / $score_board[$k]["m_peak"];
            }
            if ($r["priority"] > 0) {
                $qCur->insert($k, $r["priority"]);
            }
        } else {
            $score_board[$k]["func"] = 0;
        }
        ////// init p_score
        $score_board[$k]["p_score"] = 0;
        if ($multiplier == -1 || $score_board[$k]["priority"] > $multiplier) {
            $multiplier = $score_board[$k]["priority"];
        }
    }
    if ($multiplier <= 0) {
        $multiplier = 1;
    }
    print $multiplier . "\n";
    while ($qCur->valid() && $total_p_score > 0) {
        $bufExpire = array();
        $qCurSize = $qCur->count();
        while ($qCur->valid()) {
            $idx = $qCur->extract();
            $s = $score_board[$idx]["priority"] / $multiplier;
            // alloted score in the scheduling cycle
            //			print  $score_board[$idx]["priority"]."\n";
            if ($s < 1.0E-5) {
                $s = 1.0E-5;
            }
            if ($s > 100 - $score_board[$idx]["p_score"]) {
                $s = 100 - $score_board[$idx]["p_score"];
            }
            //if ( $s > $total_p_score)
            //	$s = $total_p_score;
            $score_board[$idx]["p_score"] += $s;
            $total_p_score -= $s;
            if ($total_p_score < 0) {
                // Hank 2015.4.6  address uneven score distribution for students with same priority
                $total_p_score = 0;
            }
            if ($score_board[$idx]["p_score"] < 100 && $score_board[$idx]["priority"] > 0) {
                $bufExpire[$idx] = $score_board[$idx]["priority"];
            }
        }
        $bufExpire = shuffle_assoc($bufExpire);
        foreach ($bufExpire as $idx => $priority) {
            $qExpire->insert($idx, $score_board[$idx]["priority"]);
        }
        if ($qCurSize > $qExpire->count() && $qExpire->valid()) {
            // need new  multiplier
            $multiplier = $score_board[$qExpire->top()]["priority"];
            print $multiplier . "\n";
        }
        $qCur = $qExpire;
        $qExpire = new ScorePriorityQueue();
        $qExpire->setExtractFlags(ScorePriorityQueue::EXTR_DATA);
    }
    foreach ($score_board as $k => $r) {
        $score_board[$k]["score"] = min($score_board[$k]["func"] * ((1 - $score_P_ratio) * 100 + $score_board[$k]["p_score"] * $score_P_ratio + $score_board[$k]["diversity"]), 100);
        if (GetSubmissionTime($score_board[$k]['id']) > $tmDeadline) {
            print "user " . $score_board[$k]['id'] . " is late\n";
            $score_board[$k]["score"] -= $LATE_SUBMISSION_PENALTY;
        }
        if ($score_board[$k]["score"] < 0) {
            $score_board[$k]["score"] = 0;
        }
        /// submission time /////
        $score_board[$k]["submission_time"] = date("n/j H:i:s", GetSubmissionTime($score_board[$k]["id"]));
        ////////////////////////
    }
    $REMAINING_P_SCORE = $total_p_score;
    ////////sort by score
    $tmp = array();
    foreach ($score_board as &$ma) {
        $tmp[] = $ma["score"] + $ma["priority"] / 1000;
    }
    array_multisort($tmp, SORT_DESC, $score_board);
}