dignea  1.0.0
Diverse Instance Generator with Novelty Search and Evolutionary Algorithms
OrderCrossover.h
Go to the documentation of this file.
1 
11 #ifndef DIGNEA_ORDERCROSSOVER_H
12 #define DIGNEA_ORDERCROSSOVER_H
13 
14 #include <dignea/core/Crossover.h>
15 #include <dignea/types/SolutionTypes.h>
16 #include <dignea/utilities/random/PseudoRandom.h>
17 
18 #include <algorithm>
19 #include <vector>
20 
21 using namespace std;
22 
29 template <class S = IntFloatSolution>
30 class OrderCrossover : public Crossover<S> {
31  public:
32  OrderCrossover() = default;
33 
34  virtual ~OrderCrossover() = default;
35 
36  inline void run(S &firstInd, S &secondInd) override;
37 
38  std::string getName() const override { return "Order Crossover"; };
39 };
40 
50 template <class S>
51 void OrderCrossover<S>::run(S &firstInd, S &secondInd) {
52  vector secondIndVars = secondInd.getVariables();
53  vector firstIndVars = firstInd.getVariables();
54  const int size = secondIndVars.size() - 1;
55 
56  int fstPoint = 1;
57  int sndPoint = 1;
58  while (fstPoint == sndPoint) {
59  fstPoint = PseudoRandom::randInt(1, size);
60  sndPoint = PseudoRandom::randInt(1, size);
61  }
62  int start = min(fstPoint, sndPoint);
63  int end = max(fstPoint, sndPoint);
64  auto startCity = 0;
65 
66  vector fstOff{startCity};
67  vector sndOff{startCity};
68  // fstOff.push_back(startCity);
69  // sndOff.push_back(startCity);
70  for (int i = start; i < end; i++) {
71  fstOff.push_back(firstIndVars[i]);
72  sndOff.push_back(secondIndVars[i]);
73  }
74 
75  for (int i = 0; i < size; i++) {
76  auto genIdx = (end + i) % size;
77  auto genFstInd = firstIndVars[genIdx];
78  auto genSndInd = secondIndVars[genIdx];
79  if (find(fstOff.begin(), fstOff.end(), genSndInd) == fstOff.end()) {
80  fstOff.push_back(genSndInd);
81  }
82  if (find(sndOff.begin(), sndOff.end(), genFstInd) == sndOff.end()) {
83  sndOff.push_back(genFstInd);
84  }
85  }
86  fstOff.push_back(startCity);
87  sndOff.push_back(startCity);
88  std::rotate(fstOff.begin() + 1, fstOff.begin() + start, fstOff.end() - 1);
89  std::rotate(sndOff.begin() + 1, sndOff.begin() + start, sndOff.end() - 1);
90  for (int i = 1; i < size; i++) {
91  firstIndVars[i] = fstOff[i];
92  secondIndVars[i] = sndOff[i];
93  }
94  firstInd.setVariables(firstIndVars);
95  secondInd.setVariables(secondIndVars);
96 }
97 
98 #endif // DIGNEA_ORDERCROSSOVER_H
Abstract Crossover interface.
Definition: Crossover.h:19
Class which defines the Order Crossover Operator from Eiben's book. Works for permutation representat...
Definition: OrderCrossover.h:30
void run(S &firstInd, S &secondInd) override
Performs the Order Crossover Operator This operator is used in permutation based problems like TSP....
Definition: OrderCrossover.h:51
static int randInt(int minBound, int maxBound)
Returns a random integer int the range [minBound, maxBound].
Definition: PseudoRandom.cpp:38