Use array_splice to compute new lists... much shorter code, and probably

a lot faster.
This commit is contained in:
dave 2010-02-22 18:13:11 +00:00
parent 61aee7f487
commit 538c2ae066

View File

@ -12,6 +12,7 @@ class annealer {
var $update_callback;
var $iterations;
var $items_per_bucket;
var $max_items_per_bucket;
var $rate;
function annealer($num_buckets, $start_temp, $start_moves, $rate,
@ -29,6 +30,7 @@ class annealer {
$this->iterations = 0;
$this->items_per_bucket = count($items) / $num_buckets;
$this->rate = $rate;
$this->max_items_per_bucket = 0;
$ipb = ceil($this->items_per_bucket);
$i=0;
$this->cost = 0;
@ -59,6 +61,10 @@ class annealer {
{
$this->update_callback = $func;
}
function set_max_items_per_bucket($num)
{
$this->max_items_per_bucket = $num;
}
function pick_move()
@ -70,13 +76,20 @@ class annealer {
}
$i1 = rand(0, count($this->bucket[$b1]) -1);
/* Pick a csecond bucket that is different thatn the first */
/* Pick a second bucket that is different than the first */
$b2 = rand(0, $this->num_buckets - 2);
if($b2 >= $b1) $b2++;
/* Picket an item, or a blank, in the second bucket */
$i2 = rand(0, count($this->bucket[$b2]));
if($i2 == count($this->bucket[$b2])) $i2 = -1;
if($this->max_items_per_bucket > 0 && count($this->bucket[$b2]) >= $this->max_items_per_bucket) {
/* Can't move b1 into b2, it would exceed the max items per bucket, pick an
* item to swap with */
$i2 = rand(0, count($this->bucket[$b2])-1);
} else {
/* Pick an item, or a blank, in the second bucket */
$i2 = rand(0, count($this->bucket[$b2]));
if($i2 == count($this->bucket[$b2])) $i2 = -1;
}
// TRACE("Move ($b1,$i1)<->($b2,$i2)\n");
return array($b1, $i1, $b2, $i2);
}
@ -104,33 +117,13 @@ class annealer {
$b1_old = $this->bucket[$b1];
$b2_old = $this->bucket[$b2];
$b1_new = array();
$b2_new = array();
/* Make 2 new bucket lists */
for($x=0; $x<count($b1_old); $x++) {
$id = $b1_old[$x];
if($x == $i1) {
/* Swap or remove this index */
if($i2 != -1) $b1_new[] = $b2_old[$i2];
} else {
$b1_new[] = $id;
}
if($i2 != -1) {
array_splice($this->bucket[$b1], $i1, 1, $b2_old[$i2]);
array_splice($this->bucket[$b2], $i2, 1, $b1_old[$i1]);
} else {
array_splice($this->bucket[$b1], $i1, 1);
$this->bucket[$b2][] = $b1_old[$i1];
}
for($x=0; $x<count($b2_old); $x++) {
$id = $b2_old[$x];
if($x == $i2) {
/* Swap or remove this index */
$b2_new[] = $b1_old[$i1];
} else {
$b2_new[] = $id;
}
}
if($i2 == -1) $b2_new[] = $b1_old[$i1];
/* Assign the new item lists to the buckets */
$this->bucket[$b1] = $b1_new;
$this->bucket[$b2] = $b2_new;
/* Compute costs */
$cost -= $this->bucket_cost[$b1];