KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
stoprique.h
Go to the documentation of this file.
1 
6 /*
7  * $Id: stoprique.h 17555 2014-09-18 07:36:52Z predoehl $
8  */
9 
10 #ifndef STOPRIQUE3_H_INCLUDED_PREDOEHL_UOFARIZONAVISION
11 #define STOPRIQUE3_H_INCLUDED_PREDOEHL_UOFARIZONAVISION 1
12 
13 #include <l/l_sys_lib.h>
14 #include <l/l_sys_rand.h>
15 #include <l_cpp/l_util.h>
16 
17 #include <qd_cpp/redblack.h>
18 
19 namespace kjb
20 {
21 namespace qd
22 {
23 
127 template< typename SATELLITE_TYPE, int POWERLAW_NUM, int POWERLAW_DEN >
129 : public DijkstraPriorityQueue< SATELLITE_TYPE >
130 {
131 
132 public:
134  typedef SATELLITE_TYPE Sat_tp;
135 
138 
141 
163  inline static Key_tp power_law()
164  {
165  return Key_tp( POWERLAW_NUM ) / Key_tp( POWERLAW_DEN );
166  }
167 
168  enum {
169  BAD_LOC = 0
170  };
171 
172 private:
173 
175  struct SatLoc {
176  Sat_tp dat;
177  Loc_tp spqloc;
178  SatLoc( const Sat_tp& sat = Sat_tp(), Loc_tp bxl = 0 )
180  : dat( sat ), spqloc( bxl )
181  {}
182  };
183 
185  typedef Redblack_subtree_sum< SatLoc > RBT;
186 
187  enum {
188  LOC_BIAS = 12345
189  };
190 
192  struct Compo {
193  RBT* subq;
194  Loc_tp loc;
195  Sat_tp sat;
196  Key_tp enr;
197 
199  Compo( RBT* pq, Loc_tp pl, const Sat_tp& ps, const Key_tp& pe )
200  : subq( pq ), loc( pl ), sat( ps ), enr( pe )
201  {}
202 
204  void clear_it()
205  {
206  subq = 00;
207  }
208 
210  bool is_cleared() const
211  {
212  return 00 == subq;
213  }
214  };
215 
217  std::vector< Compo > m_master;
218 
219 
220 
222  RBT m_always;
223 
225  RBT m_sometimes;
226 
231  RBT m_never;
232 
233 
234 
236  static inline
237  Key_tp MAX_ENERGY() { return std::numeric_limits< Key_tp >::max(); }
238 
239 
241  static inline
242  Key_tp DUMMY_WT() { return 0; }
243 
244 
251  static inline Key_tp energy2weight( const Key_tp& energy )
252  {
253  /*
254  * polynomial decay: 1/(energy + epsilon) to some positive power
255  */
256  return pow( energy, power_law() );
257 
258  /*
259  * exponential decay: base ^ {-energy}.
260  return pow( power_law(), -energy );
261  */
262  }
263 
264 
266  static inline Key_tp nice_e2w( const Key_tp& enr )
267  {
268  return 0 < enr && enr < MAX_ENERGY() ? energy2weight(enr) : DUMMY_WT();
269  }
270 
271 
272 
274  inline RBT& which_sub_queue( const Key_tp& energy )
275  {
276  if ( 0 == energy )
277  {
278  return m_always;
279  }
280  if ( MAX_ENERGY() <= energy )
281  {
282  return m_never;
283  }
284  return m_sometimes;
285  }
286 
287 
289  Loc_tp insert_here( RBT& subq, const Sat_tp& sat, const Key_tp& energy )
290  {
291  SatLoc satloc( sat, LOC_BIAS + m_master.size() );
292  Loc_tp inner_loc = subq.insert( nice_e2w( energy ), satloc );
293  m_master.push_back( Compo( & subq, inner_loc, sat, energy ) );
294  return satloc.spqloc;
295  }
296 
297 
299  Compo* ref( Loc_tp spqloc )
300  {
301  if ( spqloc < LOC_BIAS )
302  {
303  return 00;
304  }
305  register Loc_tp unbiased = spqloc - LOC_BIAS;
306  return m_master.size() <= unbiased ? 00 : & m_master[ unbiased ];
307  }
308 
309 
311  const Compo* ref( Loc_tp spqloc ) const
312  {
313  if ( spqloc < LOC_BIAS )
314  {
315  return 00;
316  }
317  register Loc_tp unbiased = spqloc - LOC_BIAS;
318  return m_master.size() <= unbiased ? 00 : & m_master[ unbiased ];
319  }
320 
321 
322 
323 public:
324 
326  size_t size() const
327  {
328  return m_always.size() + m_sometimes.size() + m_never.size();
329  }
330 
331 
333  bool is_empty() const
334  {
335  return 0 == size();
336  }
337 
338 
340  void clear()
341  {
342  m_always.clear();
343  m_sometimes.clear();
344  m_never.clear();
345  m_master.clear();
346  }
347 
348 
350  Loc_tp ins_max_key( const Sat_tp& sat )
351  {
352  return insert_here( m_never, sat, MAX_ENERGY() );
353  }
354 
355 
357  Loc_tp insert( const Key_tp& energy, const Sat_tp& sat )
358  {
359  return insert_here( which_sub_queue( energy ), sat, energy );
360  }
361 
362 
364  bool access_loc( Loc_tp spqloc, Key_tp* energy, Sat_tp* serialnum ) const
365  {
366  const Compo* ccc = ref( spqloc );
367  if ( 00 == ccc || ccc -> is_cleared() )
368  {
369  return false;
370  }
371  if ( energy )
372  {
373  *energy = ccc -> enr;
374  }
375  if ( serialnum )
376  {
377  *serialnum = ccc -> sat;
378  }
379  return true;
380  }
381 
382 
384  bool erase_loc( Loc_tp spqloc )
385  {
386  Compo* ccc = ref( spqloc );
387  if ( 00 == ccc || ccc -> is_cleared() )
388  {
389  return false;
390  }
391  bool result = ccc -> subq -> erase_loc( ccc -> loc );
392  ccc -> clear_it();
393  return result;
394  }
395 
396 
398  bool rekey_loc( Loc_tp spqloc, const Key_tp& newenergy )
399  {
400  Compo* ccc = ref( spqloc );
401  if ( 00 == ccc || ccc -> is_cleared() )
402  {
403  return false;
404  }
405  register const Key_tp oldenergy = ccc -> enr;
406  if ( newenergy == oldenergy )
407  {
408  return true; // energy has not changed so nothing to do
409  }
410  ccc -> enr = newenergy;
411 
412  // handle the common case of node that stays within the same subqueue
413  const Key_tp new_weight = nice_e2w( newenergy );
414  RBT& newsubq = which_sub_queue( newenergy );
415  if ( & newsubq == ccc -> subq ) // if node stays in same subqueue
416  {
417  return ccc -> subq -> rekey_loc( ccc -> loc, new_weight );
418  }
419 
420  // node has to hop out of one subqueue and into another
421  bool result = ccc -> subq -> erase_loc( ccc -> loc );
422  ccc -> subq = & newsubq;
423  ccc -> loc
424  = ccc -> subq -> insert( new_weight, SatLoc( ccc -> sat, spqloc ));
425  return result;
426  }
427 
428 
429 
455  {
456  const bool alwaysland_empty = m_always.is_empty();
457  if ( alwaysland_empty && m_sometimes.is_empty() )
458  {
459  return BAD_LOC;
460  }
461  const RBT& pq( alwaysland_empty ? m_sometimes : m_always );
462  Loc_tp loc( alwaysland_empty ? Loc_tp(BAD_LOC) : m_always.loc_max() );
463  if ( alwaysland_empty )
464  {
465  // Pick, at random, a value in range (0,M)
466  // where M = sum of tree's keys:
467  Key_tp seek_wt = m_sometimes.root_sum() * kjb_c::kjb_rand();
468 
469  // Now find a node n such that an inorder (by key) listing of nodes
470  // from smallest-keyed to n
471  // has a sum of keys S equal to or barely exceeding 'seek_wt' --
472  // minimal in the sense that (S - n.key) < seek_wt <= S.
473 
474  // The cumulative key sum is like the inverse CDF of the mass
475  // function,
476  // and selection via seek_wt is basically a transformation method
477  // of sampling from the inverse CDF.
478  loc = m_sometimes.loc_using_cumulative_key_sum( seek_wt );
479  }
480  SatLoc sl;
481 #ifdef TEST
482  bool found =
483 #endif
484  pq.access_loc( loc, 00, &sl );
485  KJB( ASSERT( found ) );
486  return sl.spqloc;
487  }
488 
489 
499  Loc_tp loc_min() const
500  {
501  const bool alwaysland_empty = m_always.is_empty();
502  if ( alwaysland_empty && m_sometimes.is_empty() )
503  {
504  return BAD_LOC;
505  }
506  const RBT& pq( alwaysland_empty ? m_sometimes : m_always );
507  SatLoc sl;
508  bool found = pq.access_loc( pq.loc_max(), 00, &sl );
509  KJB( ASSERT( found ) );
510  return sl.spqloc;
511  }
512 
513 
537  {
538  return low_energy_sample();
539  //return kjb_c::kjb_rand() < 0.5 ? low_energy_sample() : loc_min();
540  }
541 
542 };
543 
544 }
545 }
546 
547 #endif /* STOPRIQUE3_H_INCLUDED_PREDOEHL_UOFARIZONAVISION */
a priority queue implementing a stochastic extract-near-min method
Definition: stoprique.h:128
Int_matrix::Value_type max(const Int_matrix &mat)
Return the maximum value in this matrix.
Definition: l_int_matrix.h:1397
bool erase_loc(Loc_tp spqloc)
remove the indicated record
Definition: stoprique.h:384
bool access_loc(Loc_tp spqloc, Key_tp *energy, Sat_tp *serialnum) const
fetch the energy or satellite values of indicated record
Definition: stoprique.h:364
size_t size() const
return the number of key+value pairs in the dictionary.
Definition: redblack.h:2794
Loc_tp loc_min() const
get the locator of the record with maximum probability weight
Definition: stoprique.h:499
DijkstraPriorityQueue< SATELLITE_TYPE >::Key_tp Key_tp
alias of key type
Definition: stoprique.h:137
bool is_empty() const
predicate tests whether the queue contains no entries
Definition: stoprique.h:333
#define KJB(x)
Definition: l_util.h:9
Loc_tp ins_max_key(const Sat_tp &sat)
insert a key with infinite energy (must be relaxed before drawn)
Definition: stoprique.h:350
bool access_loc(Loc_tp query_loc, Key_tp *key_out, Sat_tp *sat_out) const
access a record via its locator, a constant-time operation.
Definition: redblack.h:2695
#define ASSERT(condition, message)
Definition: Assert.h:45
pure virtual interface for priority queue in Dijkstra's algorithm
Definition: diprique.h:72
SATELLITE_TYPE Sat_tp
alias of satellite type
Definition: stoprique.h:134
DijkstraPriorityQueue< SATELLITE_TYPE >::Loc_tp Loc_tp
alias of locator type
Definition: stoprique.h:140
Loc_tp loc_max() const
return the locator for the record with the maximum key, or 0
Definition: redblack.h:2787
Loc_tp loc_using_cumulative_key_sum(Key_tp cumulative_keysum) const
fetch a node based on inorder cumulative sum of tree keys
Definition: redblack.h:2929
size_t size() const
return the number of (valid) entries in the queue
Definition: stoprique.h:326
void clear()
destroy the tree or the linear array.
Definition: redblack.h:2442
float Key_tp
type that we use for keys
Definition: diprique.h:75
Loc_tp Dijkstra_extraction() const
method to make this and deterministic pri queue share interface
Definition: stoprique.h:536
definition of class Redblack_subtree_sum.
bool is_empty() const
return whether the size is zero
Definition: redblack.h:2801
void clear()
throw away all contents
Definition: stoprique.h:340
size_t Loc_tp
type that we use for locators
Definition: diprique.h:76
SATELLITE_TYPE Sat_tp
type of satellite data
Definition: diprique.h:74
Loc_tp insert(const Key_tp &energy, const Sat_tp &sat)
insert a key with a given energy and a given satellite value
Definition: stoprique.h:357
a good external locator is always positive, this isn't
Definition: stoprique.h:169
Loc_tp low_energy_sample() const
get the locator of a record drawn by our devious method
Definition: stoprique.h:454
bool rekey_loc(Loc_tp spqloc, const Key_tp &newenergy)
change the energy of the indicated record
Definition: stoprique.h:398
Key_tp root_sum() const
return subtree sum at root node (i.e., the sum of all keys).
Definition: redblack.h:2885
static Key_tp power_law()
parameter used in the energy ~ probability weight relation
Definition: stoprique.h:163