TProcura
Biblioteca em C++ para testes paramétricos de algoritmos, e coleção de algoritmos de procura e otimização
Loading...
Searching...
No Matches
TCodificacaoInteira.cpp
Go to the documentation of this file.
2
3int TCodificacaoInteira::nElementos = 0; // número de elementos na permutação
4TVector<int> TCodificacaoInteira::maxValor; // valor máximo para cada elemento
5const char* TCodificacaoInteira::nomesVizinhanca[] = {
6 "incDecValor",
7 "incDecPot2",
8 "trocaValor",
9 "inserir",
10 "trocaPar",
11 "inverterSegmento" };
12
17
20 for (int i = 0; i < nElementos; i++)
22 custo = -1;
23}
24
25void TCodificacaoInteira::Debug(bool completo) {
26 for (int i = 0; i < nElementos; i++)
27 printf("%d ", estado[i]);
28}
29
31 static const char* nomesCruzamento[] = {
32 "uniforme",
33 "1-ponto",
34 "2-pontos",
35 "3-pontos",
36 "4-pontos",
37 "5-pontos",
38 "6-pontos",
39 "7-pontos",
40 "8-pontos",
41 "9-pontos",
42 "10-pontos" };
43 static const char* nomesDistancias[] = {
44 "Hamming", // número de posições com valores diferentes
45 "Euclidiana", // distância euclidiana (raiz quadrada da soma dos quadrados das diferenças)
46 "Manhattan" }; // distância Manhattan (soma das diferenças absolutas)
47
49 // parametros da codificação inteira
50 parametro += {
51 { "TIPO_CRUZAR", 1, 0, 10, "Cruzamento: N - N-pontos, 0 - uniforme", nomesCruzamento, _TV("0,2,3") },
52 { "TIPO_MUTAR", 0,0,100, "Mutação: 0 - aplica um vizinho aleatório (seja 1 só elemento ou segmento), 1 a 100, probabilidade de mutação de cada elemento, em percentagem (1 a 100)", NULL, _TV("0,2,3") },
53 { "TIPO_VIZINHO", 1,1,6, "Vizinhança: vários métodso para vizinhanças de inteiros", nomesVizinhanca },
54 { "LIMITE_VIZINHOS", 0,0,1000,
55"LIMITE_VIZINHOS, conforme a vizinhança, se 0 não há limite\n\
56- incDecPot2 + trocaValor - limita a diferença máxima de valores\n\
57- inserir + trocaPar + inverterSegmento - limita a distância entre pares" },
58 { "TIPO_DISTANCIA", 1,1,3, "Distância: vários métodso para distâncias de inteiros", nomesDistancias, _TV("0,2,3") }
59 };
60}
61
65 if (pontos > nElementos / 2)
66 pontos = nElementos / 2;
67 while (divisoes.Count() < pontos) {
70 }
71 if (divisoes.Empty()) { // cruzamento uniforme
72 Debug(EXTRA_DEBUG, false, " cruzamento uniforme");
73 for (int i = 0; i < nElementos; i++)
74 estado[i] = ((TCodificacaoInteira*)(TRand::rand() % 2 == 0 ? a : b))->estado[i];
75 }
76 else { // cruzamento em N pontos
77 bool copiaPai = true;
78 int i = 0;
80 Debug(EXTRA_DEBUG, false, " cruzamento %d-ponto(s): ", divisoes.Count());
81 for (auto ponto : divisoes)
82 Debug(EXTRA_DEBUG, false, "%d ", ponto);
83 }
84 divisoes += nElementos; // ponto final
85 for(auto ponto : divisoes) {
86 while (i < ponto) {
87 estado[i] = ((TCodificacaoInteira*)(copiaPai ? a : b))->estado[i];
88 i++;
89 }
91 }
92 }
93 custo = -1;
94
96}
97
98
100 // inverter segmento de N bits
103 Debug(EXTRA_DEBUG, false, " vizinhança %s (limite %d)",
104 nomesVizinhanca[tipo - 1], limiteVizinhanca);
105
106 if (tipo >= vizIncDecValorCI && tipo <= vizTrocaValorCI) {
107 // alterar valor de um elemento
108 for (int i = 0; i < nElementos; i++) {
109 int j = 0;
110 while (abs(j) <= maxValor[i] && (!limiteVizinhanca || abs(j) <= limiteVizinhanca)) {
111 // incrementar j (+1, -1, +2, -2, +4, -4, etc no caso de potências, e incremental c.c.)
112 if (j <= 0)
113 j = -j + (tipo == vizIncDecPot2CI ? (j == 0 ? 1 : -j) : 1);
114 else
115 j = -j;
116 if (tipo == vizIncDecValorCI && j > 1)
117 break; // apenas incrementa/decrementa 1
118 if (estado[i] + j < 0 || estado[i] + j >= maxValor[i])
119 continue; // valor inválido
121 if (vizinho != NULL) {
122 vizinho->estado[i] += j;
123 vizinho->custo = -1;
124 vizinhos += vizinho;
125 }
126 else
127 memoriaEsgotada = true;
128 }
129 }
130 }
131 else if (tipo >= vizInserirCI && tipo <= vizInverterSegmentoCI) {
132 // alterar posição de elementos
133 for (int i = 0; i < nElementos; i++) // elemento i
134 for (int j = 0; j < nElementos; j++) // elemento j ou local j
135 if (i != j && (!limiteVizinhanca || abs(i - j) <= limiteVizinhanca)) {
137 if (vizinho != NULL) {
138 if (tipo == vizInserirCI) {
139 int valor = vizinho->estado[i];
140 vizinho->estado.Delete(i);
141 vizinho->estado.Insert(j < i ? j : j - 1, valor);
142 if (maxValor[i] != maxValor[j]) {
143 // garantir que os valores estão dentro dos limites
144 for (int k = (i < j ? i : j); k < (i < j ? j : i); k++)
145 vizinho->estado[k] %= maxValor[k];
146 }
147 }
148 else if (tipo == vizTrocaParCI && i < j) { // trocaPar
149 int valor = vizinho->estado[i];
150 vizinho->estado[i] = vizinho->estado[j];
151 vizinho->estado[j] = valor;
152 if (maxValor[i] != maxValor[j]) {
153 // garantir que os valores estão dentro dos limites
154 vizinho->estado[i] %= maxValor[i];
155 vizinho->estado[j] %= maxValor[j];
156 }
157 }
158 else if (tipo == vizInverterSegmentoCI && i < j) { // inverterSegmento
159 int ii = i, jj = j;
160 while (ii < jj) {
161 int valor = vizinho->estado[ii];
162 vizinho->estado[ii] = vizinho->estado[jj];
163 vizinho->estado[jj] = valor;
164 if (maxValor[ii] != maxValor[jj]) {
165 // garantir que os valores estão dentro dos limites
166 vizinho->estado[ii] %= maxValor[ii];
167 vizinho->estado[jj] %= maxValor[jj];
168 }
169 ii++;
170 jj--;
171 }
172 }
173
174 vizinho->custo = -1;
175 vizinhos += vizinho;
176 }
177 else
178 memoriaEsgotada = true;
179 }
180 }
182}
183
185 // mutação com probabilidade p de trocar cada bit
188 if (p == 0) {
189 // um vizinho aleatório
191 int i = TRand::rand() % nElementos;
192 int j = TRand::rand() % nElementos;
193 Debug(EXTRA_DEBUG, false, " mutar vizinho %s (%d,%d)",
194 nomesVizinhanca[tipo - 1], i, j);
195 if (tipo == vizIncDecValorCI) {
196 estado[i] += (TRand::rand() % 2 == 0 ? 1 : -1);
197 }
198 else if (tipo == vizIncDecValorCI) {
199 do {
200 j = 1 << (TRand::rand() % 10); // potência de 2 até 512
201 } while (j >= maxValor[i]);
202 estado[i] += (TRand::rand() % 2 == 0 ? j : -j);
203 }
204 else if (tipo == vizTrocaValorCI) {
205 estado[i] = TRand::rand() % maxValor[i];
206 }
207 else if (tipo == vizInserirCI) {
208 int valor = estado[i];
209 estado.Delete(i);
210 estado.Insert(j < i ? j : j - 1, valor);
211 }
212 else if (tipo == vizTrocaParCI) {
213 int valor = estado[i];
214 estado[i] = estado[j];
215 estado[j] = valor;
216 }
217 else if (tipo == vizInverterSegmentoCI) {
218 while (i < j) {
219 int valor = estado[i];
220 estado[i] = estado[j];
221 estado[j] = valor;
222 i++;
223 j--;
224 }
225 }
226 // garantir que os valores estão dentro dos limites
227 for (int i = 0; i < nElementos; i++)
228 estado[i] = (estado[i] + maxValor[i]) % maxValor[i];
229 custo = -1;
230 }
231 else {
232 Debug(EXTRA_DEBUG, false, " mutar prob p(%d) limiteVizinhanca %d",
234 // cada elemento com probabilidade p
235 for (int i = 0; i < nElementos; i++)
236 if (TRand::rand() % 100 < (unsigned)p) {
237 if (limiteVizinhanca) {
239 estado[i] = (estado[i] + maxValor[i]) % maxValor[i]; // garantir positivo
240 }
241 else
242 estado[i] += TRand::rand() % maxValor[i];
243 }
244 custo = -1;
245 }
246}
247
249 int dist = 0;
252 if (tipo == distEuclidianaCI) {
253 int64_t d = 0;
254 for (int i = 0; i < nElementos; i++) {
255 int64_t dif = estado[i] - obj.estado[i];
256 d += dif * dif;
257 }
258 dist = (int)d;
259 }
260 else if (tipo == distManhattanCI) {
261 for (int i = 0; i < nElementos; i++)
262 dist += abs(estado[i] - obj.estado[i]);
263 }
264 else // Hamming
265 for (int i = 0; i < nElementos; i++)
266 dist += (estado[i] != obj.estado[i]);
267 return dist;
268}
@ LIMITE_VIZINHOS_CI
@ TIPO_DISTANCIA_CI
@ TIPO_VIZINHO_CI
@ TIPO_CRUZAR_CI
@ TIPO_MUTAR_CI
ETiposDistanciaInteira
@ distEuclidianaCI
@ distManhattanCI
ETiposVizinhancaInteira
@ vizInverterSegmentoCI
@ vizIncDecPot2CI
@ vizTrocaValorCI
@ vizInserirCI
@ vizTrocaParCI
@ vizIncDecValorCI
@ EXTRA_DEBUG
Nível extra para debug muito detalhado (uso interno).
Definition TProcura.h:68
@ NIVEL_DEBUG
Nível de debug, de reduzido a completo.
Definition TProcura.h:43
TVector< int > _TV(const char *str)
Definition TVector.h:1154
void Debug(bool completo=true) override
Mostra o estado no ecrã, para debug.
void Cruzamento(TPonto a, TPonto b)
static TVector< int > maxValor
void Vizinhanca(TVector< TPonto > &vizinhos)
void ResetParametros()
Inicializa os parametros, indicadores e instâncias.
void Copiar(TPonto objecto)
Fica com uma cópia do objecto.
TPonto Duplicar(void)=0
Cria um objecto que é uma cópia deste.
virtual void Cruzamento(TPonto a, TPonto b)
int custo
Custo total, atualizada após Avaliar()
virtual void Vizinhanca(TVector< TPonto > &vizinhos)
void ResetParametros() override
Inicializa os parametros, indicadores e instâncias.
static bool memoriaEsgotada
Flag indicando problemas de memória esgotada.
Definition TProcura.h:501
int Parametro(int id) const
Definition TProcura.h:522
static int resultado
Resultado retornado pelo algoritmo na última execução.
Definition TProcura.h:493
static TVector< TParametro > parametro
Parâmetros a serem utilizados na configuração atual.
Definition TProcura.h:485
TVector< Item > & BeASet()
Converte o vetor num conjunto: remove duplicados e ordena.
Definition TVector.h:836
TVector< Item > & Insert(Item a, int index=0)
Insere um único elemento na posição indicada.
Definition TVector.h:1002
TVector< Item > & Delete(int i)
Remove o elemento na posição i deslocando os seguintes.
Definition TVector.h:817
int Count() const
Definition TVector.h:227
unsigned int rand(int seq)
Retorna o próximo valor pseudo-aleatório.
Definition TRand.cpp:46