TProcura
Biblioteca em C++ para testes paramétricos de algoritmos, e coleção de algoritmos de procura e otimização
Loading...
Searching...
No Matches
TCodificacaoPermutacao.cpp
Go to the documentation of this file.
2
3int TCodificacaoPermutacao::nElementos = 0; // número de elementos na permutação
4
9
12 for (int i = 0; i < nElementos; i++)
13 estado[i] = i;
15 custo = -1;
16}
17
18void TCodificacaoPermutacao::Debug(bool completo) {
19 for (int i = 0; i < nElementos; i++)
20 printf("%d ", estado[i]);
21}
22
25
26 // parâmetros da codificação inteira
27 parametro += {
28 { "TIPO_CRUZAR", 3, 1, 4, "TIPO_CRUZAR: 1 - PMX, 2 - Edge, 3 - Order; 4 - Cycle", {
29 "PMX","Edge","Order","Cycle" } },
30 { "TIPO_MUTAR", 0,0,0, "TIPO_MUTAR: 0 - aplica um vizinho aleatório (seja 1 só elemento ou segmento)" },
31 { "TIPO_VIZINHO", 1,1,3, "TIPO_VIZINHO: vários métodso para vizinhanças de inteiros", {
32 "inserir",
33 "trocaPar",
34 "inverterSegmento" } },
35 { "LIMITE_VIZINHOS", 0,0,1000,
36"LIMITE_VIZINHOS, conforme a vizinhança, se 0 não há limite\n\
37- inserir + trocaPar + inverterSegmento - limita a distância entre pares" },
38 { "TIPO_DISTANCIA", 1,1,3, "Distância: vários métodso para distâncias de permutações", {
39 "Hamming", // número de posições com valores diferentes
40 "Kendall tau", // número de pares fora de ordem
41 "Spearman footrule" } // soma das diferenças absolutas das posições0
42 }
43 };
44}
45
49 auto& A = ((TCodificacaoPermutacao*)a)->estado;
50 auto& B = ((TCodificacaoPermutacao*)b)->estado;
51
52 estado.Reset(-1);
53
54 // vetor de marcação (usado/copied) disponível para todos os operadores
57 usado.Reset(false);
58
59 // escolher dois pontos de corte distintos
60 while (divisoes.Count() < 2) {
62 divisoes.BeASet();
63 }
64
65 int inicio = divisoes.First();
66 int fim = divisoes.Last();
67
68 if (operador == 1) { // PMX
69 Debug(EXTRA_DEBUG, false, " cruzamento PBX %d - %d", inicio, fim);
70 // mapeamento valor -> posição em B
73 for (int i = 0; i < nElementos; i++)
74 posB[B[i]] = i;
75
76 // copiar segmento de A
77 for (int i = inicio; i <= fim; i++) {
78 estado[i] = A[i];
79 usado[A[i]] = true;
80 }
81
82 // tratar elementos de B no segmento que não foram copiados
83 for (int i = inicio; i <= fim; i++) {
84 int val = B[i];
85 if (!usado[val]) {
86 int pos = i;
87 while (true) {
88 int novoValor = A[pos];
89 int novaPos = posB[novoValor];
90 if (estado[novaPos] < 0) {
92 usado[val] = true;
93 break;
94 }
95 if (pos == novaPos) {
96 if (estado[pos] < 0) {
97 estado[pos] = val;
98 usado[val] = true;
99 }
100 break;
101 }
102 pos = novaPos;
103 }
104 }
105 }
106
107 // preencher restantes posições com elementos de B
108 for (int i = 0; i < nElementos; i++)
109 if (estado[i] < 0)
110 estado[i] = B[i];
111 }
112 else if (operador == 2) { // ERX
114 Debug(EXTRA_DEBUG, false, " cruzamento ERX");
115
116 adj.Count(nElementos);
117
118 auto addEdge = [&](int from, int to) {
119 if (adj[from].Find(to) < 0)
120 adj[from] += to;
121 };
122
123 // adicionar arestas de A
124 for (int i = 0; i < nElementos; i++) {
125 int left = A[(i - 1 + nElementos) % nElementos];
126 int right = A[(i + 1) % nElementos];
127 addEdge(A[i], left);
128 addEdge(A[i], right);
129 }
130 // adicionar arestas de B
131 for (int i = 0; i < nElementos; i++) {
132 int left = B[(i - 1 + nElementos) % nElementos];
133 int right = B[(i + 1) % nElementos];
134 addEdge(B[i], left);
135 addEdge(B[i], right);
136 }
137
139 for (int i = 0; i < nElementos; i++) {
140 estado[i] = current;
141 usado[current] = true;
142
143 // escolher próximo
144 int next = -1;
145 if (!adj[current].Empty()) {
146 int minSize = nElementos + 1;
148 for (int v : adj[current]) {
149 if (!usado[v]) {
150 int size = adj[v].Count();
151 if (size < minSize) {
152 minSize = size;
153 candidatos = {};
154 candidatos += v;
155 }
156 else if (size == minSize) {
157 candidatos += v;
158 }
159 }
160 }
161 if (!candidatos.Empty())
162 next = candidatos.Random();
163 }
164
165 if (next == -1) {
166 for (int v = 0; v < nElementos; v++)
167 if (!usado[v]) { next = v; break; }
168 }
169
170 current = next;
171 }
172 }
173 else if (operador == 3) { // OX
174 Debug(EXTRA_DEBUG,false," cruzamento OX %d - %d", inicio, fim);
175 for (int i = inicio; i <= fim; i++) {
176 estado[i] = A[i];
177 usado[A[i]] = true;
178 }
179
180 int pos = (fim + 1) % nElementos;
181 int idxB = (fim + 1) % nElementos;
182
183 while (pos != inicio) {
184 int val = B[idxB];
185 if (!usado[val]) {
186 estado[pos] = val;
187 usado[val] = true;
188 pos = (pos + 1) % nElementos;
189 }
190 idxB = (idxB + 1) % nElementos;
191 }
192 }
193 else if (operador == 4) { // CX
195 Debug(EXTRA_DEBUG, false, " cruzamento CX");
196 posB.Count(nElementos);
197 for (int i = 0; i < nElementos; i++)
198 posB[B[i]] = i;
199
200 bool fromA = true;
201 int start = 0;
202
203 while (true) {
204 while (start < nElementos && usado[start])
205 start++;
206 if (start >= nElementos)
207 break;
208
209 int pos = start;
210 do {
211 estado[pos] = fromA ? A[pos] : B[pos];
212 usado[pos] = true;
213 int val = fromA ? A[pos] : B[pos];
214 pos = posB[val];
215 } while (pos != start);
216
217 fromA = !fromA;
218 }
219 }
220}
221
223 // inverter segmento de N bits
226 Debug(EXTRA_DEBUG, false, " vizinhança %s (limite %d)",
227 parametro[TIPO_VIZINHO_CP].nomeValores[tipo - 1], limiteVizinhanca);
228 // alterar posição de elementos
229 for (int i = 0; i < nElementos; i++) // elemento i
230 for (int j = 0; j < nElementos; j++) // elemento j ou local j
231 if (i != j && (!limiteVizinhanca || abs(i - j) <= limiteVizinhanca)) {
233 if (vizinho != NULL) {
234 if (tipo == vizInserirCP) {
235 int valor = vizinho->estado[i];
236 for (int k = i; k != j; (i < j ? k++ : k--))
237 vizinho->estado[k] = vizinho->estado[i < j ? k + 1 : k - 1];
238 vizinho->estado[j] = valor;
239 }
240 else if (tipo == vizTrocaParCP && i < j) { // trocaPar
241 int valor = vizinho->estado[i];
242 vizinho->estado[i] = vizinho->estado[j];
243 vizinho->estado[j] = valor;
244 }
245 else if (tipo == vizInverterSegmentoCP && i < j) { // inverterSegmento
246 int ii = i, jj = j;
247 while (ii < jj) {
248 int valor = vizinho->estado[ii];
249 vizinho->estado[ii] = vizinho->estado[jj];
250 vizinho->estado[jj] = valor;
251 ii++;
252 jj--;
253 }
254 }
255
256 vizinho->custo = -1;
257 vizinhos += vizinho;
258 }
259 else
260 memoriaEsgotada = true;
261 }
263}
264
266 // mutação com probabilidade p de trocar cada bit
269 if (p == 0) {
270 // um vizinho aleatório
273 int i = TRand::rand() % nElementos;
274 int j = TRand::rand() % nElementos;
277 Debug(EXTRA_DEBUG, false, " mutar vizinho %s (%d,%d)",
278 parametro[TIPO_VIZINHO_CP].nomeValores[tipo - 1], i, j);
279 if (tipo == vizInserirCP) {
280 int valor = estado[i];
281 for (int k = i; k != j; (i < j ? k++ : k--))
282 estado[k] = estado[i < j ? k + 1 : k - 1];
283 estado[j] = valor;
284 }
285 else if (tipo == vizTrocaParCP) {
286 int valor = estado[i];
287 estado[i] = estado[j];
288 estado[j] = valor;
289 }
290 else if (tipo == vizInverterSegmentoCP) {
291 while (i < j) {
292 int valor = estado[i];
293 estado[i] = estado[j];
294 estado[j] = valor;
295 i++;
296 j--;
297 }
298 }
299 }
300}
301
303 int dist = 0;
307 if (tipo == distKendallTauCP) {
308 // número de pares fora de ordem
309 for(int i=0; i<nElementos-1; i++)
310 for(int j=i+1; j<nElementos; j++)
311 if (obj.estado.Find(estado[i]) > obj.estado.Find(estado[j]))
312 dist++;
313 }
314 else if (tipo == distSpearmanFootruleCP) {
315 // soma das diferenças absolutas das posições
316 for (int i = 0; i < nElementos; i++)
317 dist += abs(i - obj.estado.Find(estado[i]));
318 }
319 else // Hamming
320 for (int i = 0; i < nElementos; i++)
321 dist += (estado[i] != obj.estado[i]);
322 return dist;
323}
ETiposDistanciaPermutacao
@ distKendallTauCP
@ distSpearmanFootruleCP
@ TIPO_DISTANCIA_CP
@ LIMITE_VIZINHOS_CP
@ TIPO_MUTAR_CP
@ TIPO_VIZINHO_CP
@ TIPO_CRUZAR_CP
ETiposVizinhancaPermutacao
@ vizInverterSegmentoCP
@ EXTRA_DEBUG
Nível extra para debug muito detalhado (uso interno).
Definition TProcura.h:96
void Debug(bool completo=true) override
Mostra o estado no ecrã, para debug.
void Cruzamento(TPonto a, TPonto b)
void Vizinhanca(TVector< TPonto > &vizinhos)
TPonto Duplicar(void)=0
Cria um objecto que é uma cópia deste.
void ResetParametros()
Inicializa os parâmetros, indicadores e instâncias.
void Copiar(TPonto objecto)
Fica com uma cópia do objecto.
int custo
Custo total, atualizada após Avaliar()
virtual void Vizinhanca(TVector< TPonto > &vizinhos)
void ResetParametros() override
Inicializa os parâmetros, indicadores e instâncias.
static bool memoriaEsgotada
Flag indicando problemas de memória esgotada.
Definition TProcura.h:583
int Parametro(int id) const
Definition TProcura.h:607
static int resultado
Resultado retornado pelo algoritmo na última execução.
Definition TProcura.h:575
static TVector< TParametro > parametro
Parâmetros a serem utilizados na configuração atual.
Definition TProcura.h:567
TVector< Item > & RandomOrder()
Coloca os elementos em ordem aleatória (Fisher–Yates shuffle).
Definition TVector.h:761
TVector< Item > & Reset(Item const &i)
Preenche todo o vetor com um mesmo valor.
Definition TVector.h:793
int Count() const
Definition TVector.h:230
unsigned int rand(int seq)
Retorna o próximo valor pseudo-aleatório.
Definition TRand.cpp:46