Go to the documentation of this file.00001
00005 #include "BinManager.h"
00006 #include <cmath>
00007 #include <map>
00008
00009 namespace momdp
00010 {
00011
00012 BinManager::BinManager(BeliefValuePairPool * _initialUB, BeliefCache* _beliefCache, state_val _sval)
00013 {
00014 initialUB = _initialUB;
00015 beliefCache = _beliefCache;
00016 sval = _sval;
00017
00018 initializeDynamicBins();
00019 }
00020
00021 void BinManager::updateNode(int row)
00022 {
00023 BeliefTreeNode & node = *(beliefCache->getRow(row)->REACHABLE);
00024 if (binManagerDataTable.get(row).binned == false)
00025 {
00026 binManagerDataTable.set(row).binned = true;
00027 initializeNode(node);
00028 }
00029 else
00030 {
00031 updateBin(node);
00032 }
00033 }
00034
00035 void BinManager::initializeNode(BeliefTreeNode & node)
00036 {
00037 double lbVal = beliefCache->getRow(node.cacheIndex.row)-> LB ;
00038 double ubValue = initialUB->getValue(node.s->bvec);
00039 double entropy = 0;
00040 FOREACH_NOCONST (SparseVector_Entry, di, node.s->bvec->data)
00041 {
00042 entropy += di->value * ( log(di->value) / log(2.0) );
00043 }
00044 entropy = (-1) * entropy;
00045
00046 int i;
00047 for (i=1;i<=bin_level_count;i++)
00048 {
00049
00050 binLevels_nodes[i][node.cacheIndex.row]["ub_index"] = (int) ((ubValue - lowest) / binLevels_intervals[i]["ub_interval"] );
00051
00052 if ( binLevels_nodes[i][node.cacheIndex.row]["ub_index"] >
00053 (initial_bin_size * pow((float)bin_growth_factor,(float)(i-1))) - 1 )
00054 binLevels_nodes[i][node.cacheIndex.row]["ub_index"] =
00055 (initial_bin_size * pow((float)bin_growth_factor,(float)(i-1))) - 1;
00056 else
00057 if ( binLevels_nodes[i][node.cacheIndex.row]["ub_index"] < 0 )
00058 binLevels_nodes[i][node.cacheIndex.row]["ub_index"] = 0;
00059
00060
00061 binLevels_nodes[i][node.cacheIndex.row]["entropy_index"] = (int) (entropy / binLevels_intervals[i]["entropy_interval"]);
00062 if ( binLevels_nodes[i][node.cacheIndex.row]["entropy_index"] >
00063 (initial_bin_size * pow((float)bin_growth_factor,(float)(i-1))) - 1 )
00064 binLevels_nodes[i][node.cacheIndex.row]["entropy_index"] =
00065 (initial_bin_size * pow((float)bin_growth_factor,(float)(i-1))) - 1;
00066 else
00067 if ( binLevels_nodes[i][node.cacheIndex.row]["entropy_index"] < 0 )
00068 binLevels_nodes[i][node.cacheIndex.row]["entropy_index"] = 0;
00069
00070 char access[100];
00071 sprintf( access, "%d-%d", (int)binLevels_nodes[i][node.cacheIndex.row]["ub_index"], (int)binLevels_nodes[i][node.cacheIndex.row]["entropy_index"]);
00072
00073
00074 if ( binLevels[i]["binCount"][access] == 0 )
00075 {
00076 double err = beliefCache->getRow(node.cacheIndex.row)->UB - lbVal;
00077 binLevels_nodes[i][node.cacheIndex.row]["prev_error"] = err * err;
00078 binLevels[i]["binError"][access] = binLevels_nodes[i][node.cacheIndex.row]["prev_error"];
00079 }
00080 else
00081 {
00082 double err = binLevels[i]["bins"][access] - lbVal;
00083 binLevels_nodes[i][node.cacheIndex.row]["prev_error"] = err * err;
00084 binLevels[i]["binError"][access] += binLevels_nodes[i][node.cacheIndex.row]["prev_error"];
00085 }
00086
00087
00088 binLevels[i]["bins"][access] = ((double)(binLevels[i]["bins"][access] * binLevels[i]["binCount"][access] + lbVal)) / ((double)(binLevels[i]["binCount"][access] + 1));
00089
00090 binLevels[i]["binCount"][access] ++;
00091 }
00092 previous_lowerbound[node.cacheIndex.row] = lbVal;
00093 }
00094
00095 void BinManager::updateBin(BeliefTreeNode & node)
00096 {
00097 double lbVal = beliefCache->getRow(node.cacheIndex.row)->LB;
00098 int i;
00099 for (i=1;i<=bin_level_count;i++)
00100 {
00101 char access[100];
00102 sprintf( access, "%d-%d", (int)binLevels_nodes[i][node.cacheIndex.row]["ub_index"], (int)binLevels_nodes[i][node.cacheIndex.row]["entropy_index"]);
00103
00104
00105 if ( binLevels[i]["binCount"][access] == 1 )
00106 {
00107 double err = beliefCache->getRow(node.cacheIndex.row) ->UB - lbVal;
00108 binLevels_nodes[i][node.cacheIndex.row]["prev_error"] = err * err;
00109 binLevels[i]["binError"][access] = binLevels_nodes[i][node.cacheIndex.row]["prev_error"];
00110 }
00111 else
00112 {
00113 double err = binLevels[i]["bins"][access]- lbVal;
00114 binLevels[i]["binError"][access] -= binLevels_nodes[i][node.cacheIndex.row]["prev_error"];
00115 binLevels_nodes[i][node.cacheIndex.row]["prev_error"] = err * err;
00116 binLevels[i]["binError"][access] += binLevels_nodes[i][node.cacheIndex.row]["prev_error"];
00117 }
00118
00119
00120
00121 binLevels[i]["bins"][access] = ((double)(binLevels[i]["bins"][access] * binLevels[i]["binCount"][access] + lbVal - previous_lowerbound[node.cacheIndex.row])) / ((double)binLevels[i]["binCount"][access]);
00122 }
00123 previous_lowerbound[node.cacheIndex.row] = lbVal;
00124 }
00125
00126 void BinManager::printBinCount()
00127 {
00128 int x, y, i;
00129 for (i=1;i<=bin_level_count;i++)
00130 {
00131 cout << endl << "entropy --------------------------------------->" << endl;
00132 for (x=0;x<(initial_bin_size * pow((float)bin_growth_factor,(float)(i-1)));x++)
00133 {
00134 for(y=0;y<(initial_bin_size * pow((float)bin_growth_factor,(float)(i-1)));y++)
00135 {
00136 char access[100];
00137 sprintf( access, "%d-%d", x, y);
00138 cout << ((int)binLevels[i]["binCount"][access]) << "\t";
00139
00140 }
00141 cout << endl;
00142 }
00143 cout << endl << "level " << i << ": " << binLevels_intervals[i]["counter"] << endl;
00144 }
00145 }
00146
00147 double BinManager::getBinValue(int row)
00148 {
00149
00150 double lbVal = beliefCache->getRow(row)->LB;
00151 double ubVal = beliefCache->getRow(row)->UB;
00152 char access[100];
00153 sprintf( access, "%d-%d", (int)binLevels_nodes[1][row]["ub_index"], (int)binLevels_nodes[1][row]["entropy_index"]);
00154
00155 if ( ((int)binLevels[1]["binCount"][access]) == 1 )
00156 {
00157
00158 return ubVal;
00159 }
00160 else
00161 {
00162 int i, best_level;
00163 double smallest_error;
00164 for (i=1;i<=bin_level_count;i++)
00165 {
00166 sprintf( access, "%d-%d", (int)binLevels_nodes[i][row]["ub_index"], (int)binLevels_nodes[i][row]["entropy_index"]);
00167 if ( i == 1 )
00168 {
00169 best_level = i;
00170 smallest_error = binLevels[i]["binError"][access];
00171 }
00172
00173 if ( binLevels[i]["binError"][access] + 1e-10 < smallest_error )
00174 {
00175 best_level = i;
00176 smallest_error = binLevels[i]["binError"][access];
00177 }
00178 }
00179
00180 sprintf( access, "%d-%d", (int)binLevels_nodes[best_level][row]["ub_index"], (int)binLevels_nodes[best_level][row]["entropy_index"]);
00181
00182 binLevels_intervals[best_level]["counter"] ++;
00183
00184
00185 if ( binLevels[best_level]["bins"][access] > ubVal + 1e-10 ) return ubVal;
00186 else
00187 if ( binLevels[best_level]["bins"][access] + 1e-10 < lbVal ) return lbVal;
00188 else
00189 return binLevels[best_level]["bins"][access];
00190 }
00191 }
00192
00193 void BinManager::initializeDynamicBins()
00194 {
00195 bin_level_count = 2;
00196
00197
00198 highest = -99e10;
00199 lowest = 99e10;
00200 int numStates = initialUB->problem->getBeliefSize();
00201 FOR (i, numStates) {
00202 double value = initialUB->cornerPoints(i);
00203 if ( value > highest ) highest = value;
00204 if ( value < lowest ) lowest = value;
00205 }
00206
00207
00208 double maxEntropy = 0;
00209 maxEntropy = ((double)(1.0/numStates)) * ( log( ((double)(1.0/numStates)) ) / log(2.0) ) * (-1) * numStates;
00210
00211 int i;
00212 for (i=1;i<=bin_level_count;i++)
00213 {
00214
00215 map <string,
00216 double
00217 > intervals;
00218 intervals["ub_interval"] = (highest - lowest) / (initial_bin_size * pow((float)bin_growth_factor,(float)(i-1)));
00219 intervals["entropy_interval"] = maxEntropy / (initial_bin_size * pow((float)bin_growth_factor,(float)(i-1)));
00220 binLevels_intervals[i] = intervals;
00221
00222
00223
00224 map <int,
00225 map <string,
00226 double
00227 >
00228 > nodes;
00229 binLevels_nodes[i] = nodes;
00230
00231
00232
00233 map <string,
00234 map <string,
00235 double
00236 >
00237 > level;
00238
00239 map <string,
00240 double
00241 > bins;
00242
00243 map <string,
00244 double
00245 > binCount;
00246
00247 map <string,
00248 double
00249 > binError;
00250
00251 level["bins"] = bins;
00252 level["binCount"] = binCount;
00253 level["binError"] = binError;
00254 binLevels[i] = level;
00255 }
00256 }
00257 };