00001
00011 #include "RandomFixNumberConnections.h"
00012
00013 RandomFixNumberConnections::RandomFixNumberConnections(const double conn_prob)
00014 : conn_prob(conn_prob)
00015 {
00016 if (conn_prob <= 0 || conn_prob > 1)
00017 throw PCSIM::Exception( "RandomConnections::RandomConnections" , "Connection probability must lie in interval (0,1]" );
00018
00019 if (conn_prob != 1)
00020 uni_rnd = new UniformDistribution(0.0, 1.0);
00021 }
00022
00023
00024 RandomFixNumberConnections::RandomFixNumberConnections(const double conn_prob, MPI::Intracomm const&)
00025 : conn_prob(conn_prob)
00026 {
00027 if (conn_prob <= 0 || conn_prob > 1)
00028 throw PCSIM::Exception( "RandomConnections::RandomConnections" , "Connection probability must lie in interval (0,1]" );
00029
00030 if (conn_prob != 1)
00031 uni_rnd = new UniformDistribution(0.0, 1.0);
00032
00033 num_connections=0;
00034 }
00035
00036
00037 RandomFixNumberConnections::~RandomFixNumberConnections()
00038 {
00039 if (conn_prob != 1)
00040 delete uni_rnd;
00041
00042 num_connections=0;
00043 }
00044
00045
00046 void RandomFixNumberConnections::init(const SimObjectPopulation &srcPopulation, const SimObjectPopulation &destPopulation)
00047 {
00048 src_popul = &srcPopulation;
00049 dest_popul = &destPopulation;
00050
00051 num_connections = (unsigned int)round(conn_prob*srcPopulation.size() * destPopulation.size());
00052 }
00053
00054
00055 size_t RandomFixNumberConnections::estimate()
00056 {
00057 return num_connections;
00058 }
00059
00060
00061 void RandomFixNumberConnections::reset(SimObject::ID::SortedVector::const_iterator src_begin_it,
00062 SimObject::ID::SortedVector::const_iterator src_end_it,
00063 SimObject::ID::SortedVector::const_iterator dest_begin_it,
00064 SimObject::ID::SortedVector::const_iterator dest_end_it)
00065 {
00066 curr_src_idx = 0;
00067 curr_dest_idx = -1;
00068
00069 from_begin_it = src_begin_it;
00070 to_begin_it = dest_begin_it;
00071 src_max_idx = src_end_it - src_begin_it;
00072 dest_max_idx = dest_end_it - dest_begin_it;
00073
00074 num_connections = (unsigned int)round(conn_prob * src_max_idx * dest_max_idx);
00075 }
00076
00077
00078 bool RandomFixNumberConnections:: next( pair<SimObject::ID, SimObject::ID> &conn_pair )
00079 {
00080 last_conn_valid = false;
00081
00082 size_t step;
00083 if (conn_prob == 1)
00084 {
00085 step = 1;
00086 do
00087 {
00088 curr_dest_idx += step;
00089 if (curr_dest_idx >= dest_max_idx) {
00090 curr_src_idx += size_t(curr_dest_idx / dest_max_idx );
00091 curr_dest_idx %= dest_max_idx;
00092 }
00093 if (curr_src_idx < src_max_idx)
00094 {
00095 last_conn_idx.first = *(from_begin_it + curr_src_idx);
00096 conn_pair.first = (*src_popul).getID(last_conn_idx.first);
00097
00098 last_conn_idx.second = *(to_begin_it + curr_dest_idx);
00099 conn_pair.second = (*dest_popul).getID(last_conn_idx.second);
00100 }
00101 else
00102 return false;
00103 }
00104 while(conn_pair.first == conn_pair.second);
00105 }
00106 else if (connected_pairs.size() < num_connections)
00107 {
00108 bool found = false;
00109 int pre = 0;
00110 int post = 0;
00111
00112 do {
00113 do {
00114 pre = (int)floor(src_max_idx * (*uni_rnd)(*m_rnd_eng));
00115 post = (int)floor(dest_max_idx *(*uni_rnd)(*m_rnd_eng));
00116 }
00117 while (pre==post);
00118
00119 pair<int, int> pre_post(pre,post);
00120
00121 if(connected_pairs.find(pre_post) == connected_pairs.end()) {
00122 connected_pairs.insert(pre_post);
00123 found = true;
00124 }
00125 }
00126 while(!found);
00127
00128 last_conn_idx.first = *(from_begin_it + pre);
00129 conn_pair.first = (*src_popul).getID(last_conn_idx.first);
00130 last_conn_idx.second = *(to_begin_it + post);
00131 conn_pair.second = (*dest_popul).getID(last_conn_idx.second);
00132 }
00133 else
00134 return false;
00135
00136 last_conn_valid = true;
00137
00138 return true;
00139 }
00140