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

View File

@ -30,6 +30,7 @@
send_header("Judging teams automatic scheduler"); send_header("Judging teams automatic scheduler");
echo i18n("The scheduler is running. Depending on the effort it may take 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, 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 most of it is just information about what the scheduler is doing. You can copy
@ -58,8 +59,6 @@ echo "<br />";
echo "<br />"; echo "<br />";
TRACE("<pre>");
//function TRACE() { } //function TRACE() { }
//function TRACE_R() { } //function TRACE_R() { }
@ -67,6 +66,28 @@ function TRACE($str) { print($str); }
function TRACE_R($array) { print_r($array); } 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: /* The cost function is:
+ 50 * each judge below the min for each team + 50 * each judge below the min for each team
+ 10 * each judge above the max 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"); TRACE("\n\n");
$div = array(); $div = array();
TRACE("Loading Project Divisions...\n"); 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 judging team may judge {$config['max_projects_per_team']} projects\n");
TRACE(" Each project must be judged {$config['times_judged']} times\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[$jteam_id]['max_judges'] = 0;
$jteam_id++; $jteam_id++;
TRACE("Assigning projects to judging teams...\n"); set_status("Assigning projects to judging teams");
$keys = array_keys($jdiv); $keys = array_keys($jdiv);
for($k=0; $k<count($keys); $k++) { for($k=0; $k<count($keys); $k++) {
$jdiv_id = $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(); print mysql_error();
TRACE(" Done.\n"); TRACE(" Done.\n");
TRACE("Loading Judges...\n"); set_status("Loading Judges");
$q=mysql_query("SELECT judges.* FROM judges,judges_years WHERE ". $q=mysql_query("SELECT judges.* FROM judges,judges_years WHERE ".
"complete='yes' ". "complete='yes' ".
@ -447,9 +469,17 @@ while($r=mysql_fetch_object($q))
TRACE("Loaded ".count($judges)." judges.\n"); TRACE("Loaded ".count($judges)." judges.\n");
$jteam[0]['max_judges'] = count($judges); $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); $judge_ids = array_keys($judges);
$e = $config['effort']; $e = $config['effort'];
$a = new annealer(count($jteam), 25, $e, 0.98, judges_cost_function, $judge_ids); $a = new annealer(count($jteam), 25, $e, 0.98, judges_cost_function, $judge_ids);
$a->set_update_callback(judges_to_teams_update);
$a->anneal(); $a->anneal();
@ -568,6 +598,8 @@ print("Unused Judges:\n");
$ids = $a->bucket[0]; $ids = $a->bucket[0];
for($y=0; $y<count($ids); $y++) pr_judge($jteam[0], $ids[$y]); 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"); TRACE("Loading Timeslot Data\n");
$available_timeslots=array(); $available_timeslots=array();
$q=mysql_query("SELECT * FROM judges_timeslots WHERE ". $q=mysql_query("SELECT * FROM judges_timeslots WHERE ".
@ -651,7 +683,8 @@ function timeslot_cost_function($annealer, $bucket_id, $ids)
$keys = array_keys($jdiv); $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]; $jdiv_id = $keys[$k];
$pids = array_keys($jdiv[$jdiv_id]['projects']); $pids = array_keys($jdiv[$jdiv_id]['projects']);
$n_projects = count($pids); $n_projects = count($pids);
@ -694,6 +727,8 @@ for($k=0; $k<count($keys); $k++) {
print("Jteams ids len=".count($jteams_ids)); print("Jteams ids len=".count($jteams_ids));
print("\n"); print("\n");
set_percent(50 + ($k / $keys_count) * 50);
$e = 500 + 50 * ($config['effort'] / 1000); $e = 500 + 50 * ($config['effort'] / 1000);
$a = new annealer($n_timeslots, 100, $e, 0.98, timeslot_cost_function, $jteams_ids); $a = new annealer($n_timeslots, 100, $e, 0.98, timeslot_cost_function, $jteams_ids);
$a->set_pick_move(timeslot_pick_move); $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", array( "max_projects_per_team", "times_judged",
"min_judges_per_team", "max_judges_per_team", "min_judges_per_team", "max_judges_per_team",
"effort", "project_status") ); "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']); config_editor("Judge Scheduler", $config['FAIRYEAR'], "var", $_SERVER['PHP_SELF']);
echo "<hr />"; echo "<hr />";