RepastHPC  2.3.1
AgentSet.h
1 /*
2  * Repast for High Performance Computing (Repast HPC)
3  *
4  * Copyright (c) 2010 Argonne National Laboratory
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with
8  * or without modification, are permitted provided that the following
9  * conditions are met:
10  *
11  * Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  *
14  * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * Neither the name of the Argonne National Laboratory nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR
26  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  *
35  * AgentSet.h
36  *
37  * Created on: Jul 16, 2010
38  * Author: nick
39  */
40 
41 #ifndef AGENTSET_H_
42 #define AGENTSET_H_
43 
44 
45 #define USE_RANDOM_RELOGO_SET_OPS
46 
47 #include <vector>
48 #include <algorithm>
49 #include <iostream>
50 #include <limits>
51 
52 #include "repast_hpc/Random.h"
53 
54 namespace repast {
55 
56 namespace relogo {
57 
61 template<typename T, typename ValueGetter>
62 struct SetCmp {
63 
64  const ValueGetter* _getter;
65 
66  SetCmp(const ValueGetter* getter) :
67  _getter(getter) {
68  }
69 
70  bool operator()(T* one, T* two) {
71  return (*_getter)(one) < (*_getter)(two);
72  }
73 };
74 
81 template<typename T>
82 class AgentSet {
83 
84 public:
85  typedef typename std::vector<T*>::iterator as_iterator;
86  typedef typename std::vector<T*>::const_iterator const_as_iterator;
87 
91  AgentSet();
92 
96  template<typename input_iterator>
97  AgentSet(input_iterator start, input_iterator end);
98 
102  AgentSet(const AgentSet& set);
103 
104  virtual ~AgentSet();
105 
110  template<typename input_iterator>
111  void addAll(input_iterator begin, input_iterator end);
112 
116  void add(T* agent);
117 
126  template<typename Functor>
127  void ask(Functor func);
128 
139  template<typename Functor, typename P1>
140  void ask(Functor func, const P1& p1);
141 
151  template<typename Functor, typename P1>
152  void ask(Functor func, P1& p1);
153 
159  template<typename Functor>
160  void apply(Functor& func);
161 
167  template<typename Functor>
168  void apply(const Functor& func);
169 
176  T* at(int index);
177 
183  size_t count() const {
184  return agents.size();
185  }
186 
192  size_t size() const {
193  return agents.size();
194  }
195 
203  T* operator[](size_t index);
204 
210  as_iterator begin() {
211  return agents.begin();
212  }
213 
219  const_as_iterator begin() const {
220  return agents.begin();
221  }
222 
228  as_iterator end() {
229  return agents.end();
230  }
231 
237  const_as_iterator end() const {
238  return agents.end();
239  }
240 
244  void clear() {
245  agents.clear();
246  }
247 
260  template<typename ValueGetter>
261  T* minOneOf(const ValueGetter& getter);
262 
275  template<typename ValueGetter>
276  T* maxOneOf(const ValueGetter& getter);
277 
289  template<typename ValueGetter>
290  void withMin(const ValueGetter& getter, AgentSet<T>& set);
291 
303  template<typename ValueGetter>
304  void withMax(const ValueGetter& getter, AgentSet<T>& set);
305 
324  template<typename ValueGetter>
325  void minNOf(size_t count, const ValueGetter& getter, AgentSet<T>& set, bool initialSetIsSorted = false);
326 
345  template<typename ValueGetter>
346  void maxNOf(size_t count, const ValueGetter& getter, AgentSet<T>& set, bool initialSetIsSorted = false);
347 
352  T* oneOf();
353 
357  void remove(T* agent);
358 
362  void shuffle();
363 
364 //private:
365  std::vector<T*> agents;
366 
367 };
368 
369 template<typename T>
371 }
372 
373 template<typename T>
374 template<typename input_iterator>
375 AgentSet<T>::AgentSet(input_iterator start, input_iterator end) :
376  agents(start, end) {
377  std::random_shuffle(agents.begin(), agents.end(), uni_random);
378 }
379 
380 template<typename T>
382  agents(set.agents.begin(), set.agents.end()) {
383 }
384 
385 template<typename T>
387 }
388 
389 template<typename T>
391  std::random_shuffle(agents.begin(), agents.end(), uni_random);
392 }
393 
394 template<typename T>
395 template<typename input_iterator>
396 void AgentSet<T>::addAll(input_iterator begin, input_iterator end) {
397  agents.insert(agents.end(), begin, end);
398 }
399 
400 template<typename T>
401 T* AgentSet<T>::operator[](size_t index) {
402  return agents[index];
403 }
404 
405 template<typename T>
406 void AgentSet<T>::add(T* agent) {
407  agents.push_back(agent);
408 }
409 
410 template<typename T>
411 T* AgentSet<T>::at(int index) {
412  return agents.at(index);
413 }
414 
415 template<typename T>
416 template<typename Functor>
418  for (as_iterator iter = agents.begin(); iter != agents.end(); ++iter) {
419  func(*iter);
420  }
421 }
422 
423 template<typename T>
424 template<typename Functor>
425 void AgentSet<T>::apply(const Functor& func) {
426  for (as_iterator iter = agents.begin(); iter != agents.end(); ++iter) {
427  func(*iter);
428  }
429 }
430 
431 template<typename T>
432 template<typename Functor>
434  for (as_iterator iter = agents.begin(); iter != agents.end(); ++iter) {
435  T* target = *iter;
436  (target->*func)();
437  }
438 }
439 
440 template<typename T>
441 template<typename Functor, typename P1>
442 void AgentSet<T>::ask(Functor func, const P1& p1) {
443  for (as_iterator iter = agents.begin(); iter != agents.end(); ++iter) {
444  T* target = *iter;
445  (target->*func)(p1);
446  }
447 }
448 
449 template<typename T>
450 template<typename Functor, typename P1>
451 void AgentSet<T>::ask(Functor func, P1& p1) {
452  for (as_iterator iter = agents.begin(); iter != agents.end(); ++iter) {
453  T* target = *iter;
454  (target->*func)(p1);
455  }
456 }
457 
458 template<typename T>
459 template<typename ValueGetter>
460 T* AgentSet<T>::minOneOf(const ValueGetter& getter) {
461  if (agents.size() == 0)
462  return 0;
463 
464  std::vector<T*> mins;
465  double min = std::numeric_limits<double>::max();
466  for (as_iterator iter = agents.begin(); iter != agents.end(); ++iter) {
467  T* agent = *iter;
468  double val = getter(agent);
469  if (val < min) {
470  mins.clear();
471  mins.push_back(agent);
472  min = val;
473  } else if (val == min) {
474  mins.push_back(agent);
475  }
476  }
477 
478  if (mins.size() > 1) {
479  int index = (int) Random::instance()->createUniIntGenerator(0, mins.size() - 1).next();
480  return mins[index];
481  } else
482  return mins[0];
483 }
484 
485 template<typename T>
486 template<typename ValueGetter>
487 T* AgentSet<T>::maxOneOf(const ValueGetter& getter) {
488  if (agents.size() == 0)
489  return 0;
490 
491  std::vector<T*> maxs;
492  double max = -(std::numeric_limits<double>::max());
493  for (as_iterator iter = agents.begin(); iter != agents.end(); ++iter) {
494  T* agent = *iter;
495  double val = getter(agent);
496  if (val > max) {
497  maxs.clear();
498  maxs.push_back(agent);
499  max = val;
500  } else if (val == max) {
501  maxs.push_back(agent);
502  }
503  }
504 
505  if (maxs.size() > 1) {
506  int index = (int) Random::instance()->createUniIntGenerator(0, maxs.size() - 1).next();
507  return maxs[index];
508  } else
509  return maxs[0];
510 }
511 
512 template<typename T>
513 template<typename ValueGetter>
514 void AgentSet<T>::withMin(const ValueGetter& getter, AgentSet<T>& set) {
515  set.clear();
516  if (agents.size() == 0)
517  return;
518 
519  double min = std::numeric_limits<double>::max();
520  for (as_iterator iter = agents.begin(); iter != agents.end(); ++iter) {
521  T* agent = *iter;
522  double val = getter(agent);
523  if (val < min) {
524  set.clear();
525  set.add(agent);
526  min = val;
527  } else if (val == min) {
528  set.add(agent);
529  }
530  }
531 }
532 
533 template<typename T>
534 template<typename ValueGetter>
535 void AgentSet<T>::withMax(const ValueGetter& getter, AgentSet<T>& set) {
536  set.clear();
537  if (agents.size() == 0) return;
538  // double max = std::numeric_limits<double>::min(); // This gives smallest positive number
539  double max = std::numeric_limits<double>::max() * (-1); // CORRECTED
540  for (as_iterator iter = agents.begin(); iter != agents.end(); ++iter) {
541  T* agent = *iter;
542  double val = getter(agent);
543  if (val > max) {
544  set.clear();
545  set.add(agent);
546  max = val;
547  } else if (val == max) {
548  set.add(agent);
549  }
550  }
551 }
552 template<typename T>
553 template<typename ValueGetter>
554 void AgentSet<T>::minNOf(size_t count, const ValueGetter& getter, AgentSet<T>& set, bool initialSetIsSorted) {
555  set.clear();
556  if (size() <= count) {
557  set.addAll(begin(), end());
558  } else {
559  AgentSet<T> tmp(begin(), end());
560  if(!initialSetIsSorted){
561  SetCmp<T, ValueGetter> cmp(&getter);
562  sort(tmp.begin(), tmp.end(), cmp);
563  }
564 #ifdef USE_RANDOM_RELOGO_SET_OPS
565  int numberToAdd = count;
566  while(numberToAdd > 0){
567  double v1 = getter(tmp[0]);
568  int indx = 1;
569  while(getter(tmp[indx]) == v1) indx++;
570  if(indx <= numberToAdd){
571  for(size_t i = 0; i < indx; i++){
572  set.add(tmp[0]);
573  numberToAdd--;
574  tmp.remove(tmp[0]);
575  }
576  }
577  else{ // Must choose randomly from the remaining qualified entries
578  while(numberToAdd > 0){
579  int i = (int) Random::instance()->createUniIntGenerator(0, indx - 1).next();
580  set.add(tmp[i]);
581  numberToAdd--;
582  tmp.remove(tmp[i]);
583  indx--;
584  }
585  }
586  }
587 #else
588  for (size_t i = 0; i < count; i++) {
589  set.add(tmp[i]);
590  }
591 #endif
592  }
593 }
594 
595 template<typename T>
596 template<typename ValueGetter>
597 void AgentSet<T>::maxNOf(size_t count, const ValueGetter& getter, AgentSet<T>& set, bool initialSetIsSorted) {
598  set.clear();
599  if (size() <= count) {
600  set.addAll(begin(), end());
601  } else {
602  AgentSet<T> tmp(begin(), end());
603  if(!initialSetIsSorted){
604  SetCmp<T, ValueGetter> cmp(&getter);
605  sort(tmp.begin(), tmp.end(), cmp);
606  }
607 #ifdef USE_RANDOM_RELOGO_SET_OPS
608  int numberToAdd = count;
609  int endIndx = tmp.size() -1;
610  while(numberToAdd > 0){
611  double v1 = getter(tmp[endIndx]);
612  int indx = endIndx - 1;
613  while(getter(tmp[indx]) == v1) indx--;
614  if((endIndx - indx) <= numberToAdd){
615  while( endIndx > indx){
616  set.add(tmp[endIndx]);
617  numberToAdd--;
618  tmp.remove(tmp[endIndx]);
619  endIndx--;
620  }
621  }
622  else{ // Must choose randomly from the remaining qualified entries
623  while(numberToAdd > 0){
624  int i = (int) Random::instance()->createUniIntGenerator(indx + 1, endIndx).next();
625  set.add(tmp[i]);
626  numberToAdd--;
627  tmp.remove(tmp[i]);
628  endIndx--;
629  }
630  }
631  }
632 #else
633  for (size_t i = tmp.size() - count; i < tmp.size(); i++) {
634  set.add(tmp[i]);
635  }
636 #endif
637  }
638 }
639 
640 template<typename T>
642  size_t size = agents.size();
643  if (size == 0)
644  return 0;
645  int index = (int) Random::instance()->createUniIntGenerator(0, size - 1).next();
646  return agents[index];
647 }
648 
649 template<typename T>
650 void AgentSet<T>::remove(T* agent) {
651  typename std::vector<T*>::iterator iter = agents.begin();
652  while (iter != agents.end()) {
653  iter = std::find(iter, agents.end(), agent);
654  if (iter != agents.end())
655  iter = agents.erase(iter);
656  }
657 }
658 
659 }
660 
661 }
662 
663 #endif /* AGENTSET_H_ */
repast::relogo::AgentSet::minNOf
void minNOf(size_t count, const ValueGetter &getter, AgentSet< T > &set, bool initialSetIsSorted=false)
Gets count number of set members that have the minimum value of the number returned by ValueGetter.
Definition: AgentSet.h:554
repast::Random::instance
static Random * instance()
Gets the singleton instance of this Random.
Definition: Random.cpp:80
repast::relogo::AgentSet::operator[]
T * operator[](size_t index)
Gets the item at the specified index without doing any range checking.
Definition: AgentSet.h:401
repast::Functor
Functor interface.
Definition: Schedule.h:55
repast::relogo::AgentSet
Specialized indexable collection class for agents.
Definition: AgentSet.h:82
repast::relogo::AgentSet::minOneOf
T * minOneOf(const ValueGetter &getter)
Gets the set member that has the minimum value of the number returned by ValueGetter.
Definition: AgentSet.h:460
repast::relogo::AgentSet::at
T * at(int index)
Gets the item at the specified index.
Definition: AgentSet.h:411
repast::relogo::AgentSet::maxNOf
void maxNOf(size_t count, const ValueGetter &getter, AgentSet< T > &set, bool initialSetIsSorted=false)
Definition: AgentSet.h:597
repast::relogo::AgentSet::withMin
void withMin(const ValueGetter &getter, AgentSet< T > &set)
Gets the set members that have the minimum value of the number returned by ValueGetter,...
Definition: AgentSet.h:514
repast::relogo::AgentSet::end
const_as_iterator end() const
Gets a const iterator to the end of this AgentSet.
Definition: AgentSet.h:237
repast::relogo::AgentSet::ask
void ask(Functor func)
Calls the Functor on each agent in this AgentSet.
Definition: AgentSet.h:433
repast::relogo::AgentSet::end
as_iterator end()
Gets an iterator to the end of this AgentSet.
Definition: AgentSet.h:228
repast::relogo::AgentSet::begin
const_as_iterator begin() const
Gets a const iterator to the begining of this AgentSet.
Definition: AgentSet.h:219
repast::relogo::AgentSet::oneOf
T * oneOf()
Gets one of the members of this AgentSet at random.
Definition: AgentSet.h:641
repast::DefaultNumberGenerator::next
double next()
Gets the "next" number from this Number Generator.
Definition: Random.h:113
repast::relogo::AgentSet::add
void add(T *agent)
Adds an agent to this AgentSet.
Definition: AgentSet.h:406
repast::relogo::SetCmp
Compares two items using the specified getter.
Definition: AgentSet.h:62
repast::relogo::AgentSet::withMax
void withMax(const ValueGetter &getter, AgentSet< T > &set)
Gets the set members that have the maximum value of the number returned by ValueGetter and puts them ...
Definition: AgentSet.h:535
repast::relogo::AgentSet::begin
as_iterator begin()
Gets an iterator to the begining of this AgentSet.
Definition: AgentSet.h:210
repast::relogo::AgentSet::count
size_t count() const
Gets the size of this AgentSet.
Definition: AgentSet.h:183
repast::relogo::AgentSet::AgentSet
AgentSet()
Creates an empty agent set.
Definition: AgentSet.h:370
repast::relogo::AgentSet::size
size_t size() const
Gets the size of this AgentSet.
Definition: AgentSet.h:192
repast::relogo::AgentSet::addAll
void addAll(input_iterator begin, input_iterator end)
Adds all the agents from the start iterator through the end to this AgentSet.
Definition: AgentSet.h:396
repast::relogo::AgentSet::remove
void remove(T *agent)
Removes all instances of the specified agent from this AgentSet.
Definition: AgentSet.h:650
repast::relogo::AgentSet::clear
void clear()
Clears this AgentSet of any agents that it contains.
Definition: AgentSet.h:244
repast::relogo::AgentSet::shuffle
void shuffle()
Randomly shuffles the elements of this AgentSet.
Definition: AgentSet.h:390
repast::Random::createUniIntGenerator
IntUniformGenerator createUniIntGenerator(int from, int to)
Creates a generator that produces ints in the range [from, to].
Definition: Random.cpp:100
repast::relogo::AgentSet::apply
void apply(Functor &func)
Applies the functor to each each agent in the agent set.
Definition: AgentSet.h:417
repast::relogo::AgentSet::maxOneOf
T * maxOneOf(const ValueGetter &getter)
Gets the set member that has the maximum value of the number returned by ValueGetter.
Definition: AgentSet.h:487