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