K_Distance.cpp
Go to the documentation of this file.00001 00012 #include <K_Distance.h> 00013 00019 K_Distance::K_Distance(Population * population) { 00020 population_ = population ; 00021 numberOfFunctions_ = population_->problem_->numberOfFunctions_ ; 00022 calculatedDistance_ = 0 ; 00023 distance_ = new double*[population_->maximumPopulationSize_] ; 00024 for (int i = 0; i < population_->maximumPopulationSize_; i++) 00025 distance_[i] = new double[population_->maximumPopulationSize_] ; 00026 00027 kDistance_ = new double*[population_->maximumPopulationSize_] ; 00028 for (int i = 0; i < population_->maximumPopulationSize_; i++) 00029 kDistance_[i] = new double[population_->maximumPopulationSize_-1] ; 00030 } // K_Distance::K_Distance 00031 00037 K_Distance::~K_Distance() { 00038 for (int i = 0; i < population_->maximumPopulationSize_; i++) 00039 delete distance_[i] ; 00040 delete [] distance_ ; 00041 } // K_Distance::~K_Distance 00042 00049 void K_Distance::calculateDistanceMatrix() { 00050 for (int i = 0; i < (population_->getPopulationSize()); i++) { 00051 double minimumDistance = MAX_REAL; 00052 population_->getIth(i)->location_ = i ; // The position of the individual 00053 // in the distance matrix 00054 for (int j = 0; j < (population_->getPopulationSize()) ; j++) { 00055 if (i < j) { 00056 distance_[i][j] = getDistance(population_->getIth(i), 00057 population_->getIth(j)) ; 00058 } // if 00059 else if (i == j) 00060 distance_[i][j] = 0 ; 00061 else // (i > j) 00062 distance_[i][j] = distance_[j][i] ; 00063 #ifdef __PRINT__ 00064 //cout <<"INDIVIDUAL " << i << "\t" << *(population_->getIth(i)) << endl ; 00065 //cout <<"INDIVIDUAL " << j << "\t" << *(population_->getIth(j)) << endl ; 00066 cout << "DISTANCE("<<i<<","<<j<<")= " << distance_[i][j] << endl ; 00067 #endif 00068 00069 if ((i != j) && (distance_[i][j] < minimumDistance)) { 00070 kDistance_[i][0] = distance_[i][j] ; 00071 minimumDistance = distance_[i][j] ; 00072 } // if 00073 } // for 00074 } // for 00075 calculatedDistance_ = 1 ; 00076 #ifdef __PRINT__ 00077 cout << "________ DISTANCES ______ PopSize: " << population_->getPopulationSize() << endl ; 00078 for (int i = 0; i < population_->getPopulationSize(); i++) { 00079 for (int j = 0; j < population_->getPopulationSize(); j++) { 00080 cout << distance_[i][j]<< "\t" ; 00081 } 00082 cout << endl ; 00083 } 00084 cout << "______KDistances 0____________ " << endl ; 00085 for (int i = 0; i < population_->getPopulationSize(); i++) 00086 cout << kDistance_[i][0] << endl ; 00087 #endif 00088 } // K_Distance::calculateDistanceMatrix 00089 00090 /* 00091 * @brief Calculates the distances to the kth neighbour 00092 * 00093 * Calculates the distances among the individuals. It is assumed that 00094 * the distance to the 1st neighbour has been already calculated 00095 */ 00096 void K_Distance::calculateKDistance(int k) { 00097 #ifdef __PRINT__ 00098 cout << "CALCULATEKDISTANCE: K = " << k << endl ; 00099 #endif 00100 for (; calculatedDistance_ < k ; calculatedDistance_ ++) { 00101 // We must find the next minimun distance, excluding the so far 00102 // encountered distances. We must consider that there may be 00103 // several individuals at the same distance 00104 int lastMinimumDistanceCounter ; 00105 double lastMinimumDistance ; 00106 double nextMinimumDistance ; 00107 for (int i = 0; i < population_->getPopulationSize(); i++) { 00108 nextMinimumDistance = MAX_REAL ; 00109 lastMinimumDistanceCounter = 1 ; 00110 lastMinimumDistance = kDistance_[i][0] ; 00111 for (int j = 1 ; j < calculatedDistance_; j++) { 00112 if (kDistance_[i][j] == lastMinimumDistance) 00113 lastMinimumDistanceCounter ++ ; 00114 else { 00115 lastMinimumDistanceCounter = 1 ; 00116 lastMinimumDistance = kDistance_[i][j] ; 00117 } // else 00118 } // for 00119 for (int j = 0 ; j < population_->getPopulationSize(); j++) { 00120 if (i != j) { 00121 if (distance_[i][j] < lastMinimumDistance) 00122 ; 00123 else if (distance_[i][j] == lastMinimumDistance) { 00124 if (lastMinimumDistanceCounter == 0) 00125 nextMinimumDistance = lastMinimumDistance ; 00126 else 00127 lastMinimumDistanceCounter-- ; 00128 } // else if 00129 else { //distance_[i][j] > lastMinimumDistance 00130 if (distance_[i][j] < nextMinimumDistance) 00131 nextMinimumDistance = distance_[i][j] ; 00132 } // else 00133 } // if 00134 } // for 00135 kDistance_[i][calculatedDistance_] = nextMinimumDistance ; 00136 } // for 00137 } // for 00138 #ifdef __PRINT__ 00139 for (int i = 0 ; i < population_->getPopulationSize() ; i++) { 00140 for (int j = 0; j < calculatedDistance_; j++) 00141 // cout << "kDistance_[" << j<< "]["<<i"]: " << "\t" ; 00142 cout << kDistance_[i][j] << "\t" ; 00143 cout << endl ; 00144 } // for 00145 #endif 00146 } // K_Distance::calculateKDistance 00147 00152 int K_Distance::findMinimumDistanceIndividual() { 00153 int individual ; 00154 int kDistance ; 00155 double minimumDistance ; 00156 double previousMinimumDistance ; 00157 bool thereAreEqualDistances ; 00158 00159 individual = -1 ; 00160 kDistance = 0 ; 00161 minimumDistance = MAX_REAL ; 00162 thereAreEqualDistances = false ; 00163 //cout << "kDISTANCE: " << calculatedDistance_ << endl ; 00164 //cout << "Individuals: " << population_->getPopulationSize() << endl ; 00165 //for (int i = 0; i < population_->getPopulationSize(); i++) 00166 // cout << i << "-> " << *(population_->getIth(i)) << endl ; 00167 //cout <<"----------------------------------" << endl ; 00168 //for (int i = 0; i < population_->getPopulationSize(); i++) { 00169 // for (int j = 0; j < population_->getPopulationSize(); j++) { 00170 // cout << distance_[i][j]<< "\t" ; 00171 // } 00172 // cout << endl ; 00173 //} 00174 00175 //for (int i = 0; i < population_->getPopulationSize(); i++) 00176 // cout << kDistance_[i][0] << endl ; 00177 00178 // Search 1-Distances (kDistance == 0) 00179 for (int i = 0; 00180 (i < population_->getPopulationSize()); 00181 i++) { 00182 if (kDistance_[i][0] < minimumDistance) { 00183 minimumDistance = kDistance_[i][0] ; 00184 individual = i ; 00185 #ifdef __PRINT__ 00186 cout << "--> minimumDistance: " << minimumDistance << "\tIndividual: " << i << endl ; 00187 #endif 00188 thereAreEqualDistances = false ; 00189 } // if 00190 else if (kDistance_[i][0] == minimumDistance) 00191 thereAreEqualDistances = true ; 00192 } // for 00193 00194 if (thereAreEqualDistances) 00195 // If there are more than one individual with identical minimum 1-distance, 00196 // try with the next k-distance iteratively 00197 while (thereAreEqualDistances) { 00198 previousMinimumDistance = minimumDistance ; 00199 minimumDistance = MAX_REAL ; 00200 thereAreEqualDistances = false ; 00201 kDistance ++ ; 00202 #ifdef __PRINT__ 00203 cout << "--> kDistance: " << kDistance << endl ; 00204 #endif 00205 if ((kDistance+1) > calculatedDistance_) 00206 this->calculateKDistance(kDistance+1) ; 00207 for (int i = 0; 00208 (i < population_->getPopulationSize()) ; 00209 i++) { 00210 if (kDistance_[i][kDistance-1] == previousMinimumDistance) 00211 if (kDistance_[i][kDistance] < minimumDistance) { 00212 minimumDistance = kDistance_[i][kDistance] ; 00213 individual = i ; 00214 thereAreEqualDistances = false ; 00215 } // if 00216 else if (kDistance_[i][kDistance] == minimumDistance) 00217 thereAreEqualDistances = true ; 00218 } // for 00219 } // while 00220 00221 return individual ; 00222 } // K_Distance::findMinimumDistanceIndividual 00223 00224 00230 double K_Distance::getDistance(Individual * individual1, Individual * individual2) { 00231 double distance ; 00232 00233 distance = 0 ; 00234 for (int i = 0; i < numberOfFunctions_; i++) { 00235 distance += (individual1->fitness_[i] - individual2->fitness_[i]) * 00236 (individual1->fitness_[i] - individual2->fitness_[i]) ; 00237 #ifdef __PRINT__ 00238 cout << " individual1->fitness_" << i << individual1->fitness_[i] << endl ; 00239 cout << " individual2->fitness_" << i << individual2->fitness_[i] << endl ; 00240 cout << " distance: " << distance << endl ; 00241 #endif 00242 00243 } // for 00244 return sqrt(distance) ; 00245 } // K_Distance::getDistance 00246 00255 int K_Distance::distanceComparison(Individual * individual1, 00256 Individual * individual2) { 00257 int result ; 00258 bool finish ; 00259 int kDistance ; 00260 00261 result = 0 ; 00262 finish = false ; 00263 kDistance = 0 ; 00264 00265 int distance1 = (int)individual1->distance_ ; 00266 int distance2 = (int)individual2->distance_ ; 00267 00268 for (kDistance = 0; 00269 (kDistance < (population_->getPopulationSize()-1)) && !finish; 00270 kDistance++) { 00271 if ((kDistance+1) > calculatedDistance_) 00272 this->calculateKDistance(kDistance+1) ; 00273 00274 if (kDistance_[distance1][kDistance] < kDistance_[distance2][kDistance]) { 00275 result = -1 ; 00276 finish = true ; 00277 } // if 00278 else if (kDistance_[distance1][kDistance] > 00279 kDistance_[distance2][kDistance]) { 00280 result = 1 ; 00281 finish = true ; 00282 } // else if 00283 } // for 00284 #ifdef __PRINT__ 00285 cout << "Resultado comparar " << distance1 << "/" << distance2<<": " << result << endl ; 00286 #endif 00287 return result ; 00288 } // K_Distance::distanceComparison 00289 00290 00297 double K_Distance::getIndividualKDistance(int individual, int k) { 00298 return kDistance_[individual][k]; 00299 } // K_Distance::getIndividualKDistance