- Add status output to the judge scheduler in the form of 2 variables.

Completely untested because I don't have judge data here.  Will test when I
  get home and debug.
This commit is contained in:
dave 2006-10-25 00:53:02 +00:00
parent 65e408ce2a
commit ea418624ba
3 changed files with 61 additions and 7 deletions

View File

@ -9,6 +9,7 @@ class annealer {
var $start_temp, $start_moves;
var $cost_function_callback;
var $pick_move_callback;
var $update_callback;
var $iterations;
var $items_per_bucket;
var $rate;
@ -21,6 +22,7 @@ class annealer {
$this->start_moves = $start_moves;
$this->cost_function_callback = $cost_function_cb;
unset($this->pick_move_callback);
unset($this->update_callback);
$this->bucket_cost = array();
$this->bucket = array();
@ -53,6 +55,11 @@ class annealer {
$this->pick_move_callback = $func;
}
function set_update_callback($func)
{
$this->update_callback = $func;
}
function pick_move()
{
@ -202,6 +209,9 @@ class annealer {
return;
}
// $this->print_buckets();
$estimated_iterations = ceil(log(0.1 / $this->start_temp, $this->rate));
$iterations = 0;
while(1) {
$moves = $this->start_moves;
for($m = 0; $m<$moves; $m++) {
@ -235,7 +245,7 @@ class annealer {
// TRACE("Move rejected\n");
}
$this->iterations++;
if($this->iterations % 50000 == 0) {
if($this->iterations % 10000 == 0) {
TRACE(" {$this->iterations} iterations, cost={$this->cost}, temperature=$temperature\n");
// $this->print_buckets();
}
@ -246,7 +256,12 @@ class annealer {
break;
}
}
$iterations++;
if(isset ($this->update_callback)) {
$cb = $this->update_callback;
$cb($iterations, $estimated_iterations);
}
if($this->cost == 0) break;
if($this->cost == $last_cost) {

View File

@ -30,6 +30,7 @@
send_header("Judging teams automatic scheduler");
echo i18n("The scheduler is running. Depending on the effort it may take
several minutes to complete. It will generate a lot of output on this page,
most of it is just information about what the scheduler is doing. You can copy
@ -58,8 +59,6 @@ echo "<br />";
echo "<br />";
TRACE("<pre>");
//function TRACE() { }
//function TRACE_R() { }
@ -67,6 +66,28 @@ function TRACE($str) { print($str); }
function TRACE_R($array) { print_r($array); }
TRACE("<pre>");
function set_status($txt)
{
TRACE("Status: $txt\n");
mysql_query("UPDATE config SET val='$txt' WHERE
var='judge_scheduler_activity' AND year=0");
}
function set_progress($n)
{
$p = floor($n);
TRACE("Progress: $p\%\n");
mysql_query("UPDATE config SET val='$p' WHERE
var='judge_scheduler_precent' AND year=0");
}
set_status("Initializing...");
set_progress(0);
/* The cost function is:
+ 50 * each judge below the min for each team
+ 10 * each judge above the max for each team
@ -205,6 +226,7 @@ function jdiv_compute_cost($annealer, $bucket_id, $ids)
}
set_status("Loading Data From Database...");
TRACE("\n\n");
$div = array();
TRACE("Loading Project Divisions...\n");
@ -269,7 +291,7 @@ for($k=0; $k<count($keys); $k++) {
}
}
TRACE("Computing required judging teams...\n");
set_status("Computing required judging teams");
TRACE(" Each judging team may judge {$config['max_projects_per_team']} projects\n");
TRACE(" Each project must be judged {$config['times_judged']} times\n");
@ -295,7 +317,7 @@ $jteam[$jteam_id]['min_judges'] = 0;
$jteam[$jteam_id]['max_judges'] = 0;
$jteam_id++;
TRACE("Assigning projects to judging teams...\n");
set_status("Assigning projects to judging teams");
$keys = array_keys($jdiv);
for($k=0; $k<count($keys); $k++) {
$jdiv_id = $keys[$k];
@ -375,7 +397,7 @@ mysql_query("DELETE FROM judges_teams WHERE autocreate_type_id=1 AND year={$conf
print mysql_error();
TRACE(" Done.\n");
TRACE("Loading Judges...\n");
set_status("Loading Judges");
$q=mysql_query("SELECT judges.* FROM judges,judges_years WHERE ".
"complete='yes' ".
@ -447,9 +469,17 @@ while($r=mysql_fetch_object($q))
TRACE("Loaded ".count($judges)." judges.\n");
$jteam[0]['max_judges'] = count($judges);
function judges_to_teams_update($progress, $total)
{
set_percent(($progress * 50) / $total);
}
set_status("Assigning Judges to Teams");
$judge_ids = array_keys($judges);
$e = $config['effort'];
$a = new annealer(count($jteam), 25, $e, 0.98, judges_cost_function, $judge_ids);
$a->set_update_callback(judges_to_teams_update);
$a->anneal();
@ -568,6 +598,8 @@ print("Unused Judges:\n");
$ids = $a->bucket[0];
for($y=0; $y<count($ids); $y++) pr_judge($jteam[0], $ids[$y]);
set_status("Assigning Judging Teams and Projects to Timeslots");
TRACE("Loading Timeslot Data\n");
$available_timeslots=array();
$q=mysql_query("SELECT * FROM judges_timeslots WHERE ".
@ -651,7 +683,8 @@ function timeslot_cost_function($annealer, $bucket_id, $ids)
$keys = array_keys($jdiv);
for($k=0; $k<count($keys); $k++) {
$keys_count = count($keys);
for($k=0; $k<$keys_count; $k++) {
$jdiv_id = $keys[$k];
$pids = array_keys($jdiv[$jdiv_id]['projects']);
$n_projects = count($pids);
@ -694,6 +727,8 @@ for($k=0; $k<count($keys); $k++) {
print("Jteams ids len=".count($jteams_ids));
print("\n");
set_percent(50 + ($k / $keys_count) * 50);
$e = 500 + 50 * ($config['effort'] / 1000);
$a = new annealer($n_timeslots, 100, $e, 0.98, timeslot_cost_function, $jteams_ids);
$a->set_pick_move(timeslot_pick_move);

View File

@ -38,6 +38,10 @@ ogram; see the file COPYING. If not, write to
array( "max_projects_per_team", "times_judged",
"min_judges_per_team", "max_judges_per_team",
"effort", "project_status") );
config_editor_require_vars("Judge Scheduler Status", 0,
array( "judge_scheduler_precent",
"judge_scheduler_activity" ) );
config_editor("Judge Scheduler", $config['FAIRYEAR'], "var", $_SERVER['PHP_SELF']);
echo "<hr />";