ECF 1.5
PermutationCrsUPMX.cpp
1#include "../ECF_base.h"
2#include "Permutation.h"
3#include <map>
4
5
6namespace Permutation
7{
8
10{
11 myGenotype_->registerParameter(state, "crx.UPMX", (voidP) new double(0), ECF::DOUBLE);
12}
13
14
16{
17 voidP sptr = myGenotype_->getParameterValue(state, "crx.UPMX");
18 probability_ = *((double*)sptr.get());
19 return true;
20}
21
22// A helper class for managment of inverse indexes
24 private:
25 int * inverseIndexes; // Owned by this class
26 int * array; // Just an outer reference
27 int n; // Size of array to be indexed
28
29 public:
30 // Constructor. arr can be NULL; if not, it will be autoindexed.
31 IndexBackedPermutation(int * arr, int n_) {
32 array = arr;
33 n = n_;
34 inverseIndexes = new int[n];
35 if(array!=NULL) {
36 for(int i = 0; i < n; i++) {
37 inverseIndexes[array[i]] = i;
38 }
39 }
40 }
41
42 // Destructor.
44 delete [] inverseIndexes;
45 }
46
47 // Setter for index for given value.
48 void setIndexForValue(int value, int index) {
49 inverseIndexes[value] = index;
50 }
51
52 // Getter for index of given value.
53 int getIndexForValue(int value) {
54 return inverseIndexes[value];
55 }
56
57 // Removes element which is in array at given position.
58 // Internally, it swaps it with current last element,
59 // updates index and decreases the size of collection by one.
60 void remove(int* size, int pos) {
61 *size = *size - 1;
62
63 // swap elements
64 int t = array[*size];
65 array[*size] = array[pos];
66 array[pos] = t;
67
68 // swap element indexes
69 t = inverseIndexes[array[pos]];
70 inverseIndexes[array[pos]] = inverseIndexes[array[*size]];
71 inverseIndexes[array[*size]] = t;
72 }
73
74 // Swaps element at positions pos1 and pos2 in given
75 // permutation and updates indexes to reflect this change.
76 void swap(Permutation *p, int pos1, int pos2) {
77 // swap elements
78 int t = p->variables[pos1];
79 p->variables[pos1] = p->variables[pos2];
80 p->variables[pos2] = t;
81
82 // swap element indexes
83 t = inverseIndexes[p->variables[pos1]];
84 inverseIndexes[p->variables[pos1]] = inverseIndexes[p->variables[pos2]];
85 inverseIndexes[p->variables[pos2]] = t;
86 }
87};
88
89
90bool PermutationCrsUPMX::mate(GenotypeP gen1, GenotypeP gen2, GenotypeP child)
91{
92 Permutation* p1 = (Permutation*) (gen1.get());
93 Permutation* p2 = (Permutation*) (gen2.get());
94 Permutation* ch = (Permutation*) (child.get());
95
96 int capacity = (int) p1->getSize();
97
98 // Create an array of legal positions for swap in child;
99 // Initially, all positions are legal; later, illegal positions
100 // will be moved to end and the collection size will be decreased
101 int * legalPositions = new int[capacity];
102 for(int i = 0; i < capacity; i++) {
103 legalPositions[i] = i;
104 }
105
106 // Declare indexes for child and parent2;
107 // Create index for legal positions (it will auto-initialize).
108 IndexBackedPermutation idxCh(NULL, capacity);
109 IndexBackedPermutation idxP2(NULL, capacity);
110 IndexBackedPermutation idxLegal(legalPositions, capacity);
111
112 // Make child a clone of parent1;
113 // Initialize indexes for child and parent2
114 for(int i = 0; i < capacity; i++) {
115 ch->variables[i] = p1->variables[i];
116 idxCh.setIndexForValue(p1->variables[i], i);
117 idxP2.setIndexForValue(p2->variables[i], i);
118 }
119
120 // How many swaps we will try:
121 int attempts = capacity / 3;
122
123 // How many legal positions we actually have?
124 int legalsCount = capacity;
125
126 // Go n/3 times:
127 for(int attempt = 0; attempt < attempts; attempt++) {
128 // Pick one remaining position for parent1
129 int rand = state_->getRandomizer()->getRandomInteger(legalsCount);
130 int pos1 = legalPositions[rand];
131 idxLegal.remove(&legalsCount, rand);
132
133 // Find in parent2 the location of selected value:
134 int value1 = ch->variables[pos1];
135 int pos2 = idxP2.getIndexForValue(value1);
136
137 // Now swap in child elements at locations pos1 and pos2:
138 idxCh.swap(ch, pos1, pos2);
139
140 // If pos2 is among currently legal for picking, forbid it too:
141 if(idxLegal.getIndexForValue(pos2) < legalsCount) {
142 idxLegal.remove(&legalsCount, idxLegal.getIndexForValue(pos2));
143 }
144 }
145
146 delete [] legalPositions;
147
148 return true;
149}
150
151}
double probability_
probability of usage of this crossover operator
Definition: Crossover.h:42
GenotypeP myGenotype_
pointer to the Genotype that defines this CrossoverOp
Definition: Crossover.h:43
bool initialize(StateP)
Initialize crossover operator. Called before first crossover operation.
void registerParameters(StateP)
Register parameters with the system. Called before CrossoverOp::initialize.
bool mate(GenotypeP gen1, GenotypeP gen2, GenotypeP child)
Permutation class - implements genotype as a vector of indices 0..(n-1) (permutation of indices)
Definition: Permutation.h:37