00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 namespace Wm4
00018 {
00019
00020 template <typename Generator, typename Real>
00021 TMinHeapRecord<Generator,Real>::TMinHeapRecord ()
00022 {
00023 }
00024
00025 template <typename Generator, typename Real>
00026 TMinHeapRecord<Generator,Real>::~TMinHeapRecord ()
00027 {
00028 }
00029
00030 template <typename Generator, typename Real>
00031 Generator TMinHeapRecord<Generator,Real>::GetGenerator () const
00032 {
00033 return m_tGenerator;
00034 }
00035
00036 template <typename Generator, typename Real>
00037 Real TMinHeapRecord<Generator,Real>::GetValue () const
00038 {
00039 return m_fValue;
00040 }
00041
00042
00043
00044 template <typename Generator, typename Real>
00045 TMinHeap<Generator,Real>::TMinHeap (int iMaxQuantity, int iGrowBy)
00046 {
00047 assert(iMaxQuantity > 0 && iGrowBy > 0);
00048 m_iMaxQuantity = iMaxQuantity;
00049 m_iGrowBy = iGrowBy;
00050 m_iQuantity = 0;
00051 m_akRecords = WM4_NEW TMinHeapRecord<Generator,Real>[m_iMaxQuantity];
00052 m_apkRecords = WM4_NEW TMinHeapRecord<Generator,Real>*[m_iMaxQuantity];
00053 for (int i = 0; i < m_iMaxQuantity; i++)
00054 {
00055 m_apkRecords[i] = &m_akRecords[i];
00056 m_apkRecords[i]->m_iIndex = i;
00057 }
00058 }
00059
00060 template <typename Generator, typename Real>
00061 TMinHeap<Generator,Real>::~TMinHeap ()
00062 {
00063 WM4_DELETE[] m_akRecords;
00064 WM4_DELETE[] m_apkRecords;
00065 }
00066
00067 template <typename Generator, typename Real>
00068 int TMinHeap<Generator,Real>::GetMaxQuantity () const
00069 {
00070 return m_iMaxQuantity;
00071 }
00072
00073 template <typename Generator, typename Real>
00074 int TMinHeap<Generator,Real>::GetGrowBy () const
00075 {
00076 return m_iGrowBy;
00077 }
00078
00079 template <typename Generator, typename Real>
00080 int TMinHeap<Generator,Real>::GetQuantity () const
00081 {
00082 return m_iQuantity;
00083 }
00084
00085 template <typename Generator, typename Real>
00086 const TMinHeapRecord<Generator,Real>* TMinHeap<Generator,Real>::GetRecord (
00087 int i) const
00088 {
00089 if (0 <= i && i < m_iQuantity)
00090 {
00091 return m_apkRecords[i];
00092 }
00093 return 0;
00094 }
00095
00096 template <typename Generator, typename Real>
00097 const TMinHeapRecord<Generator,Real>* TMinHeap<Generator,Real>::Insert (
00098 Generator tGenerator, Real fValue)
00099 {
00100
00101 if (m_iQuantity == m_iMaxQuantity)
00102 {
00103 int iNewQuantity = m_iMaxQuantity + m_iGrowBy;
00104
00105 TMinHeapRecord<Generator,Real>* akNewRecords =
00106 WM4_NEW TMinHeapRecord<Generator,Real>[iNewQuantity];
00107
00108 TMinHeapRecord<Generator,Real>** apkNewRecords =
00109 WM4_NEW TMinHeapRecord<Generator,Real>*[iNewQuantity];
00110
00111
00112 size_t uiSize = m_iMaxQuantity*sizeof(TMinHeapRecord<Generator,Real>);
00113 memcpy(akNewRecords,m_akRecords,uiSize);
00114
00115
00116 int i;
00117 for (i = 0; i < m_iMaxQuantity; i++)
00118 {
00119 int iByteOffset = (int)(m_apkRecords[i] - m_akRecords);
00120 apkNewRecords[i] = (TMinHeapRecord<Generator,Real>*)(
00121 ((char*)akNewRecords) + iByteOffset);
00122 apkNewRecords[i]->m_iIndex = i;
00123 }
00124
00125
00126 for (i = m_iMaxQuantity; i < iNewQuantity; i++)
00127 {
00128 apkNewRecords[i] = &akNewRecords[i];
00129 apkNewRecords[i]->m_iIndex = i;
00130 }
00131
00132 WM4_DELETE[] m_akRecords;
00133 WM4_DELETE[] m_apkRecords;
00134 m_iMaxQuantity = iNewQuantity;
00135 m_akRecords = akNewRecords;
00136 m_apkRecords = apkNewRecords;
00137 }
00138
00139
00140
00141 int iChild = m_iQuantity++;
00142 TMinHeapRecord<Generator,Real>* pkRecord = m_apkRecords[iChild];
00143 pkRecord->m_tGenerator = tGenerator;
00144 pkRecord->m_fValue = fValue;
00145
00146
00147
00148 while (iChild > 0)
00149 {
00150 int iParent = (iChild - 1)/2;
00151 if (m_apkRecords[iParent]->m_fValue <= fValue)
00152 {
00153
00154
00155 break;
00156 }
00157
00158
00159
00160
00161
00162 m_apkRecords[iChild] = m_apkRecords[iParent];
00163 m_apkRecords[iChild]->m_iIndex = iChild;
00164
00165
00166 m_apkRecords[iParent] = pkRecord;
00167 m_apkRecords[iParent]->m_iIndex = iParent;
00168
00169 iChild = iParent;
00170 }
00171
00172 return m_apkRecords[iChild];
00173 }
00174
00175 template <typename Generator, typename Real>
00176 void TMinHeap<Generator,Real>::Remove (Generator& rtGenerator, Real& rfValue)
00177 {
00178
00179 TMinHeapRecord<Generator,Real>* pkRoot = m_apkRecords[0];
00180 rtGenerator = pkRoot->m_tGenerator;
00181 rfValue = pkRoot->m_fValue;
00182
00183
00184
00185
00186 int iLast = --m_iQuantity;
00187 TMinHeapRecord<Generator,Real>* pkRecord = m_apkRecords[iLast];
00188 int iParent = 0, iChild = 1;
00189 while (iChild <= iLast)
00190 {
00191 if (iChild < iLast)
00192 {
00193
00194
00195 int iChildP1 = iChild + 1;
00196 if (m_apkRecords[iChild]->m_fValue >
00197 m_apkRecords[iChildP1]->m_fValue)
00198 {
00199 iChild = iChildP1;
00200 }
00201 }
00202
00203 if (m_apkRecords[iChild]->m_fValue >= pkRecord->m_fValue)
00204 {
00205
00206 break;
00207 }
00208
00209
00210 m_apkRecords[iParent] = m_apkRecords[iChild];
00211 m_apkRecords[iParent]->m_iIndex = iParent;
00212
00213 iParent = iChild;
00214 iChild = 2*iChild + 1;
00215 }
00216
00217
00218
00219
00220 m_apkRecords[iParent] = pkRecord;
00221 m_apkRecords[iParent]->m_iIndex = iParent;
00222
00223
00224
00225 m_apkRecords[iLast] = pkRoot;
00226 m_apkRecords[iLast]->m_iIndex = iLast;
00227 }
00228
00229 template <typename Generator, typename Real>
00230 void TMinHeap<Generator,Real>::Update (
00231 const TMinHeapRecord<Generator,Real>* pkConstRecord, Real fValue)
00232 {
00233
00234
00235 TMinHeapRecord<Generator,Real>* pkRecord =
00236 (TMinHeapRecord<Generator,Real>*)pkConstRecord;
00237
00238 int iParent, iChild, iChildP1, iMaxChild;
00239
00240 if (fValue > pkRecord->m_fValue)
00241 {
00242 pkRecord->m_fValue = fValue;
00243
00244
00245
00246 iParent = pkRecord->m_iIndex;
00247 iChild = 2*iParent + 1;
00248 while (iChild < m_iQuantity)
00249 {
00250
00251 if (iChild < m_iQuantity-1)
00252 {
00253
00254 iChildP1 = iChild + 1;
00255 if (m_apkRecords[iChild]->m_fValue <=
00256 m_apkRecords[iChildP1]->m_fValue)
00257 {
00258 iMaxChild = iChild;
00259 }
00260 else
00261 {
00262 iMaxChild = iChildP1;
00263 }
00264 }
00265 else
00266 {
00267
00268 iMaxChild = iChild;
00269 }
00270
00271 if (m_apkRecords[iMaxChild]->m_fValue >= fValue)
00272 {
00273
00274
00275 break;
00276 }
00277
00278
00279
00280
00281
00282 m_apkRecords[iParent] = m_apkRecords[iMaxChild];
00283 m_apkRecords[iParent]->m_iIndex = iParent;
00284
00285
00286 m_apkRecords[iMaxChild] = pkRecord;
00287 m_apkRecords[iMaxChild]->m_iIndex = iMaxChild;
00288
00289 iParent = iMaxChild;
00290 iChild = 2*iParent + 1;
00291 }
00292 }
00293 else if (fValue < pkRecord->m_fValue)
00294 {
00295 pkRecord->m_fValue = fValue;
00296
00297
00298
00299 iChild = pkRecord->m_iIndex;
00300 while (iChild > 0)
00301 {
00302
00303 iParent = (iChild - 1)/2;
00304
00305 if (m_apkRecords[iParent]->m_fValue <= fValue)
00306 {
00307
00308
00309 break;
00310 }
00311
00312
00313
00314
00315
00316 m_apkRecords[iChild] = m_apkRecords[iParent];
00317 m_apkRecords[iChild]->m_iIndex = iChild;
00318
00319
00320 m_apkRecords[iParent] = pkRecord;
00321 m_apkRecords[iParent]->m_iIndex = iParent;
00322
00323 iChild = iParent;
00324 }
00325 }
00326 }
00327
00328 template <typename Generator, typename Real>
00329 bool TMinHeap<Generator,Real>::IsValid (int iStart, int iFinal)
00330 {
00331 for (int iChild = iStart; iChild <= iFinal; iChild++)
00332 {
00333 int iParent = (iChild - 1)/2;
00334 if (iParent > iStart)
00335 {
00336 if (m_apkRecords[iParent]->m_fValue >
00337 m_apkRecords[iChild]->m_fValue)
00338 {
00339 return false;
00340 }
00341
00342 if (m_apkRecords[iParent]->m_iIndex != iParent)
00343 {
00344 return false;
00345 }
00346 }
00347 }
00348
00349 return true;
00350 }
00351
00352 template <typename Generator, typename Real>
00353 bool TMinHeap<Generator,Real>::IsValid ()
00354 {
00355 return IsValid(0,m_iQuantity-1);
00356 }
00357
00358 template <typename Generator, typename Real>
00359 void TMinHeap<Generator,Real>::Print (const char* acFilename)
00360 {
00361 std::ofstream kOStr(acFilename);
00362 for (int i = 0; i < m_iQuantity; i++)
00363 {
00364 TMinHeapRecord<Generator,Real>* pkRecord = m_apkRecords[i];
00365 kOStr << pkRecord->m_iIndex << ": gen = " << pkRecord->m_tGenerator
00366 << " , val = " << pkRecord->m_fValue << std::endl;
00367 }
00368 kOStr.close();
00369 }
00370
00371 }