- 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;
// 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();
/* For each student on the tour */
foreach($ids as $x=>$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 */
$rank_cost = -1;
foreach($s['rank'] as $rank=>$rank_tid) {
if($rank_tid != $tid) continue;
$rank_cost = ($rank * $rank * 5) - 5;
if(count($s['rank']) == 0) {
/* The student hasn't made any selection, assume they
* are ok whereever we put them. */
$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) {
/* Coulnd't find tour id in the student ranks*/
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;
} 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;
}
}
// TRACE(" -> rank cost $rank_cost\n");
$cost += $rank_cost;
/* Check for student below/above grade range */
@ -155,7 +173,7 @@ function tour_cost_function($annealer, $bucket_id, $ids)
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;
}
@ -180,7 +198,7 @@ while($r=mysql_fetch_object($q)) {
$tours[$x]['grade_max'] = $r->grade_max;
$tours[$x]['id'] = $r->id;
$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++;
}
@ -189,35 +207,41 @@ TRACE("Loading Students...\n");
$q=mysql_query("SELECT students.id,students.grade,
students.registrations_id,
students.schools_id,
students.firstname, students.lastname,
tours_choice.rank,tours_choice.tour_id
students.firstname, students.lastname
FROM students
LEFT JOIN tours_choice ON (tours_choice.students_id=students.id)
LEFT JOIN registrations ON (registrations.id=students.registrations_id)
WHERE
students.year='{$config['FAIRYEAR']}'
AND tours_choice.year='{$config['FAIRYEAR']}'
AND registrations.status='complete'
ORDER BY
students.id, tours_choice.rank
students.id
");
$last_sid = -1;
TRACE(mysql_error());
while($r=mysql_fetch_object($q)) {
$sid = $r->id;
if($last_sid != $sid) {
$students[$sid]['name'] = $r->firstname.' '.$r->lastname;
$students[$sid]['grade'] = $r->grade;
$students[$sid]['registrations_id'] = $r->registrations_id;
$students[$sid]['rank'] = array();
$students[$sid]['schools_id'] = $r->schools_id;
$last_sid = $sid;
}
$students[$sid]['rank'][$r->rank] = $r->tour_id;
$students[$sid]['name'] = $r->firstname.' '.$r->lastname;
$students[$sid]['grade'] = $r->grade;
$students[$sid]['registrations_id'] = $r->registrations_id;
$students[$sid]['rank'] = array();
$students[$sid]['schools_id'] = $r->schools_id;
}
$student_ids = array_keys($students);
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)
{
set_percent(($progress * 50) / $total);
@ -233,7 +257,7 @@ $a->anneal();
/* Record the assignments */
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];
@ -241,7 +265,7 @@ foreach($tours as $x=>$t) {
foreach($sids as $sid) {
$s = $students[$sid];
$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
(`students_id`,`registrations_id`,
`tour_id`,`year`,`rank`)