diff --git a/admin/judges_sa.php b/admin/judges_sa.php
index a5ad4d7..87b2978 100644
--- a/admin/judges_sa.php
+++ b/admin/judges_sa.php
@@ -28,6 +28,7 @@
function TRACE()
{
}
+//function TRACE($str) { print($str); }
function TRACE_R()
{
}
@@ -57,11 +58,11 @@ function pick_random_move(&$team)
}
- TRACE("Random move: ($t1,$j1) ($t2,$j2)
");
+ TRACE("Random move: ($t1,$j1) ($t2,$j2)\n");
TRACE_R($team[$t1]['judges']);
- TRACE("
T2:");
+ TRACE("T2:\n");
TRACE_R($team[$t2]['judges']);
- TRACE("
");
+ TRACE("\n");
/* The move is team1,judge1 <==> team2,judge2 */
return array($t1, $j1, $t2, $j2);
}
@@ -95,7 +96,7 @@ function compute_team_cost(&$teams, &$judges, $team_id)
$cost += $min * 20;
$cost += $max * 10;
-// TRACE("Under min=$min, over max=$max
");
+// TRACE("Under min=$min, over max=$max\n");
/* For each judge on the team, score their preferences */
reset($t['judges']);
@@ -107,13 +108,13 @@ function compute_team_cost(&$teams, &$judges, $team_id)
$dpref = $j['divprefs'][$t['division']];
$cpref = $j['catprefs'][$t['category']];
-// TRACE("Judge $judge_id cp=$cpref, dp=$dpref
");
+// TRACE("Judge $judge_id cp=$cpref, dp=$dpref\n");
$cost += 2 * (-$dpref + 2);
$cost += 2 * (-$cpref + 2);
}
- TRACE("Team $team_id, cost is $cost
");
+ TRACE("Team $team_id, cost is $cost\n");
return $cost;
}
@@ -179,9 +180,9 @@ function compute_delta_cost(&$teams, &$judges, $move)
$c2 = compute_team_cost($teams, $judges, $tid2);
$cost += $c1 + $c2;
- TRACE("Team $tid1 cost {$t1['cost']} -> $c1
");
- TRACE("Team $tid2 cost {$t2['cost']} -> $c2
");
- TRACE("Delta = $cost
");
+ TRACE("Team $tid1 cost {$t1['cost']} -> $c1\n");
+ TRACE("Team $tid2 cost {$t2['cost']} -> $c2\n");
+ TRACE("Delta = $cost\n");
$t1['judges'] = $ja1;
$t2['judges'] = $ja2;
@@ -206,9 +207,9 @@ function record_move(&$teams, $move, $movedata)
TRACE("T1:");
TRACE_R($t1['judges']);
- TRACE("
T2:");
+ TRACE("\nT2:");
TRACE_R($t2['judges']);
- TRACE("
");
+ TRACE("\n");
// TRACE_R($t1);
// TRACE_R($t2);
@@ -223,30 +224,15 @@ function record_move(&$teams, $move, $movedata)
*
* - judges
*/
-function judges_assign_anneal($divisions, $categories, $judges, $data)
+function judges_assign_anneal($divisions, $categories, $languages, $judges, &$team, $data)
{
- /* Create an array to hold the team data */
- $team = array();
-
-
- $t=0;
- reset($data['teams']);
- while( list($div, $c) = each($data['teams']) ){
- reset($c);
- while( list($cat, $num) = each($c) ) {
- for($x=0; $x<$num; $x++) {
- $team[$t]['division'] = $div;
- $team[$t]['category'] = $cat;
- $team[$t]['min'] = $data['min_judges_per_team'];
- $team[$t]['max'] = $data['max_judges_per_team'];
- $team[$t]['judges'] = array();
- $t++;
- }
- }
- }
-
- $num_teams = $t;
+ $num_teams = count($team);
$x=0;
+
+ TRACE("Input: $num_teams juding teams \n");
+
+ if($num_teams <= 0) return;
+
/* Inital assignment of judges to teams */
reset($judges);
while( list($j, $ji) = each($judges)) {
@@ -257,7 +243,7 @@ function judges_assign_anneal($divisions, $categories, $judges, $data)
/* Compute inital costs */
$current_cost = 0;
// reset($team);
- for($x=0; $x");
+ TRACE("r=$r, exp=$e\n");
if($r < exp(-$delta_c / $temperature)) {
/* Yes, we do, record the move */
record_move($team, $move, $movedata);
@@ -288,21 +274,18 @@ function judges_assign_anneal($divisions, $categories, $judges, $data)
$n_accepted++;
if($current_cost < $best_cost)
$best_cost = $current_cost;
- TRACE("Move accepted, cost=$current_cost
");
+ TRACE("Move accepted, cost=$current_cost\n");
} else {
- TRACE("Move rejected
");
+ TRACE("Move rejected\n");
}
}
- TRACE("Cost is $current_cost
");
+ TRACE("Cost is $current_cost\n");
$temperature *= 0.9;
if($temperature <= 0.05) break;
}
-
- return $team;
-
}
@@ -314,6 +297,11 @@ $q=mysql_query("SELECT * FROM projectcategories WHERE year='".$config['FAIRYEAR'
while($r=mysql_fetch_object($q))
$cat[$r->id]=$r->category;
+$langr = array();
+$q=mysql_query("SELECT * FROM languages WHERE active='Y'");
+while($r=mysql_fetch_object($q))
+ $langr[] = $r->lang;
+
$configq=mysql_query("SELECT * FROM judges_schedulerconfig WHERE year='".$config['FAIRYEAR']."'");
$data=array();
@@ -321,39 +309,145 @@ while($configr=mysql_fetch_object($configq))
$data[$configr->var]=$configr->val;
$data['teams'] = array();
+$data['projects'] = array();
+$jdivisions = array();
+/* Load a list of all projects, and build an array of projects in each
+ * category */
+// print_r($langr);
+$q=mysql_query("SELECT * FROM projects WHERE year='".$config['FAIRYEAR']."'");
+while($r=mysql_fetch_object($q)) {
+ $d_id = $r->projectdivisions_id;
+ $c_id = $r->projectcategories_id;
+ $l_id = $r->language;
+
+ $data['projects'][$r->id]['timetable'] = array();
+
+
+ if(!in_array($l_id, $langr)) $l_id = 'en';
+
+ $jdivisions[$d_id][$c_id][$l_id][] = $r->id;
+
+ TRACE("Found project id {$r->id} in $d_id, $c_id, $l_id\n\n");
+}
+
+
+$t=0;
+$max_ts = 0;
foreach($div AS $d_id=>$d_val)
{
foreach($cat AS $c_id=>$c_val)
{
- $numq=mysql_query("SELECT COUNT(id) AS num FROM projects WHERE projectcategories_id='$c_id' AND projectdivisions_id='$d_id'");
- $numr=mysql_fetch_object($numq);
- $numteams=ceil($numr->num/$data['max_projects_per_team']*$data['num_times_judged']);
- $data['teams'][$d_id][$c_id]=$numteams;
+ foreach($langr AS $l_id) {
+ $num = count($jdivisions[$d_id][$c_id][$l_id]);
+
+ if($num <= 0) continue;
+ $numteams=ceil($num/$data['max_projects_per_team']*$data['num_times_judged']);
+
+ if($numteams < $data['num_times_judged'])
+ $numteams = $data['num_times_judged'];
+ TRACE("Judging teams for $d_id, $c_id, $l_id is $numteams\n\n");
+
+ $start_t = $t;
+ for($x=0; $x<$numteams; $x++) {
+ $team[$t]['division'] = $d_id;
+ $team[$t]['category'] = $c_id;
+ $team[$t]['language'] = $l_id;
+ $team[$t]['min'] = $data['min_judges_per_team'];
+ $team[$t]['max'] = $data['max_judges_per_team'];
+ $team[$t]['judges'] = array();
+ $t++;
+ }
+
+ TRACE("Created judging teams $start_t -> ".($t - 1)."\n\n");
+
+ TRACE("Need to assign these teams to $num projects: ");
+// print_r($jdivisions[$d_id][$c_id][$l_id]);
+ TRACE("\n\n");
+ /* We just created teams $start_t -> $t-1, now we can assign which projects
+ * they judge in different timeslots */
+ /* Each project must be judged $data['num_times_judged'], and each team is
+ * allowed to judge $data['num_times_judged'] projects */
+ $x=0; /* Cycles over 0 -> $num */
+ $ts=1; /* Current timeslot , increment when all judging teams are assinged */
+ $j=0; /* Cycles over o0 -> $numteams */
+ $teams_at_this_ts = array();
+ $num_done = 0;
+ while(1) {
+
+ TRACE("x=$x ");
+ if($x == $num) $x=0;
+
+ /* Get the project id we want to look at */
+ $p = $jdivisions[$d_id][$c_id][$l_id][$x];
+ TRACE(" project=$p \n\n");
+
+ TRACE("This projects has ".(count($data['projects'][$p]['timetable']))." judging teams\n");
+
+ /* See if this project needs more judges */
+ if(count($data['projects'][$p]['timetable']) == $data['num_times_judged']) {
+ /* No, this project doesn't need any more judging teams */
+ TRACE(" This project doesn't need more teams, skipping\n\n");
+// print_r($data['projects'][$p]['timetable']);
+ TRACE("\n\n");
+ if($data['projects'][$p]['timetable_done'] != 1) {
+ $data['projects'][$p]['timetable_done'] = 1;
+ $num_done++;
+
+ if($num_done == $num) break;
+ }
+ $x++;
+ continue;
+ }
+
+ /* Find a judging team to assign */
+
+ TRACE("Starting at team=$j\n\n");
+ while(1) {
+ TRACE("j=$j");
+ if($j == $numteams) $j = 0;
+ $jteam = $j + $start_t;
+
+ TRACE(" team=$jteam\n\n");
+ if(in_array($jteam, $teams_at_this_ts)) {
+ $j++;
+ continue;
+ }
+
+ if(!in_array($jteam, $data['projects'][$p]['timetable'])) {
+ /* Add this juding team to the timetable */
+ TRACE("Project $p, timeslot $ts = judging team $jteam\n\n");
+ $data['projects'][$p]['timetable'][$ts] = $jteam;
+ $teams_at_this_ts[] = $jteam;
+ $j++;
+ break;
+ }
+ $j++;
+ if($j==$numteams) $j=0;
+ }
+ $x++;
+ if(count($teams_at_this_ts) == $numteams) {
+ $ts++;
+ $teams_at_this_ts = array();
+ if($ts > $max_ts) $max_ts = $ts;
+ }
+
+ }
+ }
+
}
}
-/*
-$data = array( 'min_per_team' => 2,
- 'max_per_team' => 4,
- 'teams' => array() );
-$data['teams']['S']['LS'] = 4;
-$data['teams']['S']['PS'] = 4;
-$data['teams']['S']['Case'] = 3;
-$data['teams']['S']['CS'] = 2;
-$data['teams']['I']['LS'] = 3;
-$data['teams']['I']['PS'] = 3;
-$data['teams']['I']['Case'] = 2;
-$data['teams']['I']['CS'] = 1;
-$data['teams']['J']['LS'] = 2;
-$data['teams']['J']['PS'] = 2;
-$data['teams']['J']['Case'] = 1;
-$data['teams']['J']['CS'] = 4;
-*/
+//print_r($data['projects']);
+TRACE("Teams: ".count($team)."\n");
+//print_r($team);
-$q=mysql_query("SELECT * FROM judges WHERE complete='yes' AND judges_years.year='{$config['FAIRYEAR']}' AND judges_years.judges_id=judges.id");
+TRACE("\n");
+
+$q=mysql_query("SELECT judges.* FROM judges,judges_years WHERE complete='yes' AND judges_years.year='{$config['FAIRYEAR']}' AND judges_years.judges_id=judges.id");
$judges=array();
+
while($r=mysql_fetch_object($q))
{
unset($divprefs);
@@ -384,11 +478,12 @@ while($r=mysql_fetch_object($q))
);
}
+//print_r($judges);
//echo nl2br(TRACE_R($judges, true));
-$teams = judges_assign_anneal($div,$cat, $judges, $data);
+judges_assign_anneal($div,$cat, $langr, $judges, $team, $data);
-//TRACE_R( $teams);
+//print_r( $team);
$teamnums=array();
send_header("Judging teams automatic scheduler");
@@ -401,13 +496,36 @@ echo "".i18n("Manage Judge Members").""
echo "
";
echo "
";
+
+print("Project Timeslots:
\n");
+print("Project ID | ");
+for($x=0;$x<$max_ts;$x++) {
+ print("Slot ".($x + 1)." | ");
+}
+print("
");
+while(list($proj_id, $projinfo) = each( $data['projects'] )) {
+ print("$proj_id | ");
+ $last_slot = 1;
+ while(list($slot,$jteam) = each ($projinfo['timetable']) ) {
+ while($last_slot != $slot) {
+ print(" | ");
+ $last_slot++;
+ }
+ print("".($jteam+1)." | ");
+ $last_slot++;
+ }
+ print("
");
+}
+print("
");
+
+
$totalcost=0;
-while(list($tn, $t) = each($teams)) {
+while(list($tn, $t) = each($team)) {
//team numbers start with 0 in the annealer, but we want them to start at 1, so just tn++ here.
$tn++;
print("Team $tn: ({$div[$t['division']]}({$t['division']}),{$cat[$t['category']]}({$t['category']})) ".
- "(cost:{$t['cost']} )
");
+ "(cost:{$t['cost']} )
\n");
$totalcost+=$t['cost'];
if(!$teamnums[$t['division']][$t['category']]) $teamnums[$t['division']][$t['category']]=1;
@@ -418,7 +536,7 @@ while(list($tn, $t) = each($teams)) {
while(list($key, $j) = each($t['judges']) ) {
$judge = $judges[$j];
- print(" {$judge['name']}
");
+ print(" {$judge['name']}
\n");
mysql_query("INSERT INTO judges_teams_link (judges_id,judges_teams_id,captain,year) VALUES ('{$judge['judges_id']}','$team_id','{$judge['willing_chair']}','{$config['FAIRYEAR']}')");
}