diff --git a/admin/anneal.inc.php b/admin/anneal.inc.php index 3bc606c..7f8439b 100644 --- a/admin/anneal.inc.php +++ b/admin/anneal.inc.php @@ -8,6 +8,7 @@ class annealer { var $cost; var $start_temp, $start_moves; var $cost_function_callback; + var $pick_move_callback; var $iterations; var $items_per_bucket; var $rate; @@ -19,6 +20,7 @@ class annealer { $this->start_temp = $start_temp; $this->start_moves = $start_moves; $this->cost_function_callback = $cost_function_cb; + unset($this->pick_move_callback); $this->bucket_cost = array(); $this->bucket = array(); @@ -46,6 +48,11 @@ class annealer { "Cost={$this->cost}\n"); } + function set_pick_move($func) + { + $this->pick_move_callback = $func; + } + function pick_move() { @@ -81,6 +88,10 @@ class annealer { { list($b1, $i1, $b2, $i2) = $move; + if($b1 == $b2) { + return $this->compute_delta_cost_same_bucket($move); + } + $cost = 0; $b1_old = $this->bucket[$b1]; @@ -130,20 +141,53 @@ class annealer { return array($cost, array($c1, $b1_new, $c2, $b2_new)); } + function compute_delta_cost_same_bucket($move) + { + list($b1, $i1, $b2, $i2) = $move; + + $cost = 0; + + $b_old = $this->bucket[$b1]; + + $b_new = array(); + /* Make a new bucket list */ + for($x=0; $xbucket[$b1] = $b_new; + + /* Compute costs */ + $cost -= $this->bucket_cost[$b1]; + + $c1 = $this->cost_function($b1); + $cost += $c1; + + /* Return to the original bucket lists */ + $this->bucket[$b1] = $b_old; + + return array($cost, array($c1, $b_new, 0, array())); + } + function accept_move($move, $movedata) { list($b1, $i1, $b2, $i2) = $move; list($c1, $b1_new, $c2, $b2_new) = $movedata; -// TRACE("Old buckets:\n"); -// $this->print_bucket($b1); -// $this->print_bucket($b2); + $this->bucket[$b1] = $b1_new; - $this->bucket[$b2] = $b2_new; -// TRACE("New buckets:\n"); -// $this->print_bucket($b1); -// $this->print_bucket($b2); $this->bucket_cost[$b1] = $c1; - $this->bucket_cost[$b2] = $c2; + if($b1 != $b2) { + $this->bucket[$b2] = $b2_new; + $this->bucket_cost[$b2] = $c2; + } } function anneal() @@ -153,17 +197,22 @@ class annealer { $last_cost = 0; $last_cost_count = 0; - if($this->num_buckets <= 1) { - TRACE("Only one Bucket, nothing to anneal.\n"); - return; - } +// if($this->num_buckets <= 1) { +// TRACE("Only one Bucket, nothing to anneal.\n"); +// return; +// } // $this->print_buckets(); while(1) { $moves = $this->start_moves; for($m = 0; $m<$moves; $m++) { // $this->print_buckets(); /* Pick 2 moves at random */ - $move = $this->pick_move(); + if(isset ($this->pick_move_callback)) { + $cb = $this->pick_move_callback; + $move = $cb($this); + } else { + $move = $this->pick_move(); + } /* See what the new cost is compared to the old */ list($delta_c, $movedata) = $this->compute_delta_cost($move); @@ -178,7 +227,7 @@ class annealer { $this->accept_move($move, $movedata); $current_cost += $delta_c; $n_accepted++; - if($current_cost < $this->cost) + // if($current_cost < $this->cost) $this->cost = $current_cost; // TRACE("Move accepted, cost=$current_cost\n"); } else { diff --git a/admin/judges_sa.php b/admin/judges_sa.php index c70c624..6ec3fbd 100644 --- a/admin/judges_sa.php +++ b/admin/judges_sa.php @@ -312,9 +312,12 @@ for($k=0; $kanneal(); + $jdiv[$jdiv_id]['jteams'] = array(); for($x=0;$x<$a->num_buckets; $x++) { $bkt = $a->bucket[$x]; TRACE(" SubTeam $x:\n"); + $jdiv[$jdiv_id]['jteams'][] = $jteam_id; + $jteam[$jteam_id]['id'] = $jteam_id; $jteam[$jteam_id]['projects'] = $a->bucket[$x]; $jteam[$jteam_id]['sub'] = $x; @@ -350,7 +353,7 @@ $willing_chair_question_id = questions_find_question_id("judgereg", $config['FAI printf("Judge Willing Chair = Question ID $willing_chair_question_id\n"); /* Clean out the judging teams that were autocreated */ -TRACE("Deleting existing judging teams:"); +TRACE("Deleting existing divisional judging teams:"); $q = mysql_query("SELECT * FROM judges_teams WHERE autocreate_type_id=1 AND year={$config['FAIRYEAR']}"); while($r = mysql_fetch_object($q)) { $jteam_id = $r->id; @@ -582,29 +585,178 @@ while($r=mysql_fetch_object($q)) { $x++; } +$n_timeslots = count($available_timeslots); -TRACE("Assigning Judging Teams and Projects to Timeslots...\n"); -for($x=1;$xbucket[0]) - 1); + + /* Find the start and end of this project timeslots */ + $i_s = floor($i1 / $n_timeslots) * $n_timeslots; + $i_e = $i_s + $n_timeslots - 1; + + /* THe second number must be between $i_s and $i_e */ + $b2 = 0; + while(1) { + $i2 = rand($i_s, $i_e); + if($i2 != $i1) break; + } +// TRACE("Move=($b1, $i1, $b2, $i2)\n"); + return array($b1, $i1, $b2, $i2); +} + + +/* Computes the cost of everything, since we slice the data two + * ways we can't really use delta costs + * In this, the bucket_id will always be 1, because we don't + * actually use buckets */ +function timeslot_cost_function($annealer, $bucket_id, $ids) +{ + global $project_index; + global $jteam; + global $n_timeslots; + + $cost = 0; + +// print("Count $ids=".count($ids)); + + /* The pick_move function ensures that projects can't + * move out of a jteam so we dont' need to check that */ + + + /* First, check to see if the project is being judged 3 or + * more times in a row, OR, if it has large gaps that aren't + at the end of the judging */ + + for($x=0; $x 2) $cost += $z_count; + $r_count++; + $z_count=0; + if($r_count > 2) $cost += $r_count; + } + } + } + + /* Check to make sure a judge isn't judging two projects + * at the same time */ + $n_pids = count($project_index); + for($offset = 0; $offset < $n_timeslots; $offset++) { + for($x=0; $x<$n_pids-1; $x++) { + $o1 = $x * ($n_timeslots) + $offset; + $jteam_id1 = $ids[$o1]; + if($jteam_id1 == 0) continue; + for($y=$x+1; $y<$n_pids; $y++) { + $o2 = $y * ($n_timeslots) + $offset; + $jteam_id2 = $ids[$o2]; + if($jteam_id1 == $jteam_id2) + $cost += 50; + } + } + } + return $cost; + +} + + +$keys = array_keys($jdiv); +for($k=0; $kset_pick_move(timeslot_pick_move); + $a->anneal(); + + for($x=0; $xbucket[0][$idx]; + TRACE(($y+1).":$jteam_id "); + + if($jteam_id == 0) continue; + + /* if jteam_id isn't 0, instert it into the db */ + mysql_query("INSERT INTO judges_teams_timeslots_link ". " (judges_teams_id,judges_timeslots_id,year)". - " VALUES ('{$jteam[$x]['team_id']}', ". + " VALUES ('{$jteam[$jteam_id]['team_id']}', ". " '{$available_timeslots[$y]['id']}', ". " '{$config['FAIRYEAR']}')"); - mysql_query("INSERT INTO judges_teams_timeslots_projects_link ". + mysql_query("INSERT INTO judges_teams_timeslots_projects_link ". " (judges_teams_id,judges_timeslots_id,projects_id,year) ". - " VALUES ('{$jteam[$x]['team_id']}', ". + " VALUES ('{$jteam[$jteam_id]['team_id']}', ". " '{$available_timeslots[$y]['id']}', ". " '$pid', '{$config['FAIRYEAR']}')"); + + } + TRACE("\n"); } - print("\n"); + } TRACE("All Done.\n");