From d3d88d4cc5fa0d4fa23fedb3c7dbd5c44038bebe Mon Sep 17 00:00:00 2001 From: verel Date: Mon, 23 Jun 2014 08:11:47 +0200 Subject: [PATCH] Add MPX crossover --- eo/src/eoPartiallyMappedXover.h | 126 +++++++++++++++++++++++++++ eo/test/t-eoPartiallyMappedXover.cpp | 71 +++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 eo/src/eoPartiallyMappedXover.h create mode 100644 eo/test/t-eoPartiallyMappedXover.cpp diff --git a/eo/src/eoPartiallyMappedXover.h b/eo/src/eoPartiallyMappedXover.h new file mode 100644 index 000000000..16b23f6c9 --- /dev/null +++ b/eo/src/eoPartiallyMappedXover.h @@ -0,0 +1,126 @@ +/* + + Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 + + Sébastien Verel + + This software is governed by the CeCILL license under French law and + abiding by the rules of distribution of free software. You can ue, + modify and/ or redistribute the software under the terms of the CeCILL + license as circulated by CEA, CNRS and INRIA at the following URL + "http://www.cecill.info". + + In this respect, the user's attention is drawn to the risks associated + with loading, using, modifying and/or developing or reproducing the + software by the user in light of its specific status of free software, + that may mean that it is complicated to manipulate, and that also + therefore means that it is reserved for developers and experienced + professionals having in-depth computer knowledge. Users are therefore + encouraged to load and test the software's suitability as regards their + requirements in conditions enabling the security of their systems and/or + data to be ensured and, more generally, to use and operate it in the + same conditions as regards security. + The fact that you are presently reading this means that you have had + knowledge of the CeCILL license and that you accept its terms. + + ParadisEO WebSite : http://paradiseo.gforge.inria.fr + Contact: paradiseo-help@lists.gforge.inria.fr +*/ +#ifndef eoPartiallyMappedXover__h +#define eoPartiallyMappedXover__h + +//----------------------------------------------------------------------------- + +#include +#include + +/** + * + * Partially Mapped CrossOver (PMX) + * for permutation representation + * + */ +template +class eoPartiallyMappedXover : public eoQuadOp +{ +public: + /** + * + * @param _solution1 The first solution + * @param _solution2 The second solution + * @return true if the solution has changed + */ + bool operator()(EOT & _solution1, EOT & _solution2) { + if (_solution1.size() > 1) { + // random indexes such that i1 < i2 + int i1 = rng.random(_solution1.size()); + int i2 = rng.random(_solution1.size()); + + while (i1 == i2) + i2 = rng.random(_solution1.size()); + + if (i1 > i2) { + int tmp = i1; + i1 = i2; + i2 = tmp; + } + + // the permutations between s1 and s2 + int * p1 = new int[_solution1.size()]; + int * p2 = new int[_solution1.size()]; + + int i; + for(i = 0; i < _solution1.size(); i++) { + p1[i] = -1; + p2[i] = -1; + } + + for(i = i1; i <= i2; i++) { + p1[ _solution2[i] ] = _solution1[i] ; + p2[ _solution1[i] ] = _solution2[i] ; + } + + // replace if necessary + for(i = 0; i < i1; i++) { + while (p1[ _solution1[i] ] != -1) + _solution1[i] = p1[_solution1[i]]; + while (p2[ _solution2[i] ] != -1) + _solution2[i] = p2[_solution2[i]]; + } + + // swap between solution1 and solution2 for [i1..i2] + for(i = i1; i <= i2; i++) { + _solution1[i] = p2[ _solution1[i] ]; + _solution2[i] = p1[ _solution2[i] ]; + } + + // replace if necessary + for(i = i2 + 1; i < _solution1.size(); i++) { + while (p1[ _solution1[i] ] != -1) + _solution1[i] = p1[_solution1[i]]; + while (p2[ _solution2[i] ] != -1) + _solution2[i] = p2[_solution2[i]]; + } + + // invalidate the solutions because they have been modified + _solution1.invalidate(); + _solution2.invalidate(); + + delete [] p1; + delete [] p2; + + return true; + } else + return false; + } + + /** + * The class name. + */ + virtual std::string className() const { + return "eoPartiallyMappedXover"; + } + +}; + +#endif diff --git a/eo/test/t-eoPartiallyMappedXover.cpp b/eo/test/t-eoPartiallyMappedXover.cpp new file mode 100644 index 000000000..371c45a18 --- /dev/null +++ b/eo/test/t-eoPartiallyMappedXover.cpp @@ -0,0 +1,71 @@ +/* + +*/ + +#include +#include + +#include + +#include +#include + +//----------------------------------------------------------------------------- + +typedef eoInt Solution; + +int main() { + + std::cout << "[t-eoPartiallyMappedXover] => START" << std::endl; + + Solution sol1, sol2; + sol1.resize(9); + sol2.resize(9); + + for(int i = 0; i < sol1.size(); i++) + sol1[i] = i; + + sol2[0] = 3; + sol2[1] = 4; + sol2[2] = 1; + sol2[3] = 0; + sol2[4] = 7; + sol2[5] = 6; + sol2[6] = 5; + sol2[7] = 8; + sol2[8] = 2; + + std::cout << sol1 << std::endl; + std::cout << sol2 << std::endl; + + eoPartiallyMappedXover xover; + xover(sol1, sol2); + + std::cout << "apres" << std::endl; + std::cout << sol1 << std::endl; + std::cout << sol2 << std::endl; + + int verif[9]; + for(int i = 0; i < sol1.size(); i++) + verif[i] = -1; + + for(int i = 0; i < sol1.size(); i++) + verif[ sol1[i] ] = 1; + + for(int i = 0; i < sol1.size(); i++) + assert(verif[i] != -1); + + + for(int i = 0; i < sol2.size(); i++) + verif[i] = -1; + + for(int i = 0; i < sol2.size(); i++) + verif[ sol2[i] ] = 1; + + for(int i = 0; i < sol2.size(); i++) + assert(verif[i] != -1); + + std::cout << "[t-eoPartiallyMappedXover] => OK" << std::endl; + + return EXIT_SUCCESS; +}