- Updates to the tour annealer:

- Add more verbose output for the terminal
	- Split the student load / tour preference load to capture student who
	  didn't select any tours
	- Allow students with no tour selection to be placed anywhere with no
	  penalty
	- Add a missing break; in cost computation (doesn't change the result)
This commit is contained in:
dave 2008-04-02 06:25:50 +00:00
parent 6d3f518648
commit d2868f3f45

View File

@ -119,27 +119,45 @@ function tour_cost_function($annealer, $bucket_id, $ids)
$cost += $under * 200; $cost += $under * 200;
// TRACE("Under min=$min, over max=$max\n"); // TRACE("Under min=$min, over max=$max\n");
// TRACE("($bucket_id) {$t['id']} #{$t['num']} {$t['name']} (cap:{$t['capacity']} grade:{$t['grade_min']}-{$t['grade_max']})\n");
$schools = array(); $schools = array();
/* For each student on the tour */ /* For each student on the tour */
foreach($ids as $x=>$sid) { foreach($ids as $x=>$sid) {
$s =& $students[$sid]; $s =& $students[$sid];
// $tids = implode(' ', $s['rank']);
// TRACE(" - {$s['name']} ($tids) (g:{$s['grade']} sid:{$sid} sch:{$s['schools_id']})\n");
/* Score the rank */ /* Score the rank */
$rank_cost = -1; if(count($s['rank']) == 0) {
foreach($s['rank'] as $rank=>$rank_tid) { /* The student hasn't made any selection, assume they
if($rank_tid != $tid) continue; * are ok whereever we put them. */
$rank_cost = ($rank * $rank * 5) - 5; $rank_cost = 0;
// TRACE(" -> No choices!\n");
} else {
$rank_cost = -1;
foreach($s['rank'] as $rank=>$rank_tid) {
// TRACE(" -> Searching for tid $tid at rank $rank -> $rank_tid\n");
if($rank_tid != $tid) continue;
$rank_cost = ($rank * $rank * 5) - 5;
// TRACE(" -> matched tid $tid at rank $rank\n");
break;
}
} }
if($rank_cost == -1) { if($rank_cost == -1) {
/* Coulnd't find tour id in the student ranks*/ /* Coulnd't find tour id in the student ranks*/
if(count($s['rank']) < $config['tours_choices_max']) { if(count($s['rank']) < $config['tours_choices_max']) {
/* Student didn't choose their max # of tours,
* give a slightly lower cost */
$rank_cost = ($config['tours_choices_max']-1) * ($config['tours_choices_max']-1) * 5; $rank_cost = ($config['tours_choices_max']-1) * ($config['tours_choices_max']-1) * 5;
} else { } else {
/* Student chose max tours and they're in a
* tour they didn't pick, big cost. */
$rank_cost = $config['tours_choices_max'] * $config['tours_choices_max'] * 5; $rank_cost = $config['tours_choices_max'] * $config['tours_choices_max'] * 5;
} }
} }
// TRACE(" -> rank cost $rank_cost\n");
$cost += $rank_cost; $cost += $rank_cost;
/* Check for student below/above grade range */ /* Check for student below/above grade range */
@ -155,7 +173,7 @@ function tour_cost_function($annealer, $bucket_id, $ids)
if($cnt == 1) $cost += 2; if($cnt == 1) $cost += 2;
} }
// TRACE("Team $bucket_id, cost is $cost\n"); // TRACE("Final for bucket $bucket_id, cost is $cost\n");
return $cost; return $cost;
} }
@ -180,7 +198,7 @@ while($r=mysql_fetch_object($q)) {
$tours[$x]['grade_max'] = $r->grade_max; $tours[$x]['grade_max'] = $r->grade_max;
$tours[$x]['id'] = $r->id; $tours[$x]['id'] = $r->id;
$tours[$x]['name'] = $r->name; $tours[$x]['name'] = $r->name;
TRACE(" ($x) ${$r->id}: #{$r->num} {$r->name} (c:{$r->capacity} g:{$r->grade_min}-{$r->grade_max})\n"); TRACE(" ($x) ${$r->id}: #{$r->num} {$r->name} (cap:{$r->capacity} grade:{$r->grade_min}-{$r->grade_max})\n");
$x++; $x++;
} }
@ -189,35 +207,41 @@ TRACE("Loading Students...\n");
$q=mysql_query("SELECT students.id,students.grade, $q=mysql_query("SELECT students.id,students.grade,
students.registrations_id, students.registrations_id,
students.schools_id, students.schools_id,
students.firstname, students.lastname, students.firstname, students.lastname
tours_choice.rank,tours_choice.tour_id
FROM students FROM students
LEFT JOIN tours_choice ON (tours_choice.students_id=students.id)
LEFT JOIN registrations ON (registrations.id=students.registrations_id)
WHERE WHERE
students.year='{$config['FAIRYEAR']}' students.year='{$config['FAIRYEAR']}'
AND tours_choice.year='{$config['FAIRYEAR']}'
AND registrations.status='complete'
ORDER BY ORDER BY
students.id, tours_choice.rank students.id
"); ");
$last_sid = -1; $last_sid = -1;
TRACE(mysql_error()); TRACE(mysql_error());
while($r=mysql_fetch_object($q)) { while($r=mysql_fetch_object($q)) {
$sid = $r->id; $sid = $r->id;
if($last_sid != $sid) { $students[$sid]['name'] = $r->firstname.' '.$r->lastname;
$students[$sid]['name'] = $r->firstname.' '.$r->lastname; $students[$sid]['grade'] = $r->grade;
$students[$sid]['grade'] = $r->grade; $students[$sid]['registrations_id'] = $r->registrations_id;
$students[$sid]['registrations_id'] = $r->registrations_id; $students[$sid]['rank'] = array();
$students[$sid]['rank'] = array(); $students[$sid]['schools_id'] = $r->schools_id;
$students[$sid]['schools_id'] = $r->schools_id;
$last_sid = $sid;
}
$students[$sid]['rank'][$r->rank] = $r->tour_id;
} }
$student_ids = array_keys($students); $student_ids = array_keys($students);
TRACE(" ".(count($student_ids))." students loaded\n"); TRACE(" ".(count($student_ids))." students loaded\n");
TRACE("Loading Tour Selection Preferences...\n");
$q=mysql_query("SELECT * FROM tours_choice WHERE
tours_choice.year='{$config['FAIRYEAR']}'
ORDER BY rank ");
TRACE(mysql_error());
$x=0;
while($r=mysql_fetch_object($q)) {
$sid = $r->students_id;
if(!array_key_exists($sid, $students)) continue;
$students[$sid]['rank'][$r->rank] = $r->tour_id;
$x++;
}
TRACE(" $x preferences loaded.\n");
function tours_assignment_update($progress, $total) function tours_assignment_update($progress, $total)
{ {
set_percent(($progress * 50) / $total); set_percent(($progress * 50) / $total);
@ -233,7 +257,7 @@ $a->anneal();
/* Record the assignments */ /* Record the assignments */
foreach($tours as $x=>$t) { foreach($tours as $x=>$t) {
TRACE("($x) {$t['id']} #{$t['num']} {$t['name']} (c:{$t['capacity']} g:{$t['grade_min']}-{$t['grade_max']})\n"); TRACE("($x) {$t['id']} #{$t['num']} {$t['name']} (cap:{$t['capacity']} grade:{$t['grade_min']}-{$t['grade_max']})\n");
$sids = $a->bucket[$x]; $sids = $a->bucket[$x];
@ -241,7 +265,7 @@ foreach($tours as $x=>$t) {
foreach($sids as $sid) { foreach($sids as $sid) {
$s = $students[$sid]; $s = $students[$sid];
$tids = implode(' ', $s['rank']); $tids = implode(' ', $s['rank']);
TRACE(" - {$s['name']} ($tids) (g:{$s['grade']} s:{$s['schools_id']})\n"); TRACE(" - {$s['name']} ($tids) (g:{$s['grade']} sid:{$sid} sch:{$s['schools_id']})\n");
mysql_query("INSERT INTO tours_choice mysql_query("INSERT INTO tours_choice
(`students_id`,`registrations_id`, (`students_id`,`registrations_id`,
`tour_id`,`year`,`rank`) `tour_id`,`year`,`rank`)