[Avida-SVN] r2363 - development/source/tools
brysonda at myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Fri Feb 22 16:33:31 PST 2008
Author: brysonda
Date: 2008-02-22 19:33:31 -0500 (Fri, 22 Feb 2008)
New Revision: 2363
Modified:
development/source/tools/cWeightedIndex.cc
development/source/tools/cWeightedIndex.h
Log:
Change the behavior of cWeightedIndex to avoid subtree/parent node weight mismatches that can occur due to floating point rounding error. Extreme differences in merit magnitude can cause cascade differences in subtree weighting, leading to gaps within the tree.
Addresses [ticket:9 trac://9].
Modified: development/source/tools/cWeightedIndex.cc
===================================================================
--- development/source/tools/cWeightedIndex.cc 2008-02-22 20:02:31 UTC (rev 2362)
+++ development/source/tools/cWeightedIndex.cc 2008-02-23 00:33:31 UTC (rev 2363)
@@ -43,21 +43,40 @@
{
}
-void cWeightedIndex::AdjustSubtree(int id, double weight_change)
-{
- subtree_weight[id] += weight_change;
- if(subtree_weight[id] < 0.0001) //bb: added to catch round off error
- subtree_weight[id] = 0.0;
- if (id != 0) {
- AdjustSubtree(GetParent(id), weight_change);
- }
-}
+// The following method is subject to floating point rounding errors that can lead to weight mismatches
+// Instead, as implemented below, directly add the subtree weights to ensure that this doesn't happen. @DMB
+
+//void cWeightedIndex::AdjustSubtree(int id, double weight_change)
+//{
+// subtree_weight[id] += weight_change;
+// if(subtree_weight[id] < 0.0001) //bb: added to catch round off error
+// subtree_weight[id] = 0.0;
+// if (id != 0) {
+// AdjustSubtree(GetParent(id), weight_change);
+// }
+//}
+//
+//void cWeightedIndex::SetWeight(int id, double in_weight)
+//{
+// const double weight_change = in_weight - item_weight[id];
+// item_weight[id] = in_weight;
+// AdjustSubtree(id, weight_change);
+//}
+
void cWeightedIndex::SetWeight(int id, double in_weight)
{
- const double weight_change = in_weight - item_weight[id];
item_weight[id] = in_weight;
- AdjustSubtree(id, weight_change);
+
+ while (true) {
+ const int left_id = GetLeftChild(id);
+ const int right_id = GetRightChild(id);
+ const double left_subtree = (left_id >= size) ? 0.0 : subtree_weight[left_id];
+ const double right_subtree = (right_id >= size) ? 0.0 : subtree_weight[right_id];
+ subtree_weight[id] = item_weight[id] + left_subtree + right_subtree;
+ if (id == 0) break;
+ id = GetParent(id);
+ }
}
// This order of testing is about 10% faster than the one used below.
Modified: development/source/tools/cWeightedIndex.h
===================================================================
--- development/source/tools/cWeightedIndex.h 2008-02-22 20:02:31 UTC (rev 2362)
+++ development/source/tools/cWeightedIndex.h 2008-02-23 00:33:31 UTC (rev 2363)
@@ -47,8 +47,6 @@
tArray<double> subtree_weight;
- void AdjustSubtree(int id, double weight_change);
-
cWeightedIndex(); // @not_implemented
public:
More information about the Avida-cvs
mailing list