TProcura
Biblioteca em C++ para testes paramétricos de algoritmos, e coleção de algoritmos de procura e otimização
Loading...
Searching...
No Matches
OitoDamas.cpp
Go to the documentation of this file.
1#include "OitoDamas.h"
2#include <stdio.h>
3
4int COitoDamas::nDamas = 8; // número de damas desta instância
5
9
13
15{
17 if (clone != NULL)
18 clone->damas = damas;
19 else
20 memoriaEsgotada = true;
21 return clone;
22}
23
25{
27 damas = {};
30 else {
33 .readLines();
34 if (linhas.Count() > 0)
35 nDamas = atoi(*linhas.First());
36 }
37}
38
40{
43}
44
50
52{
53 int novaLinha = damas.Count();
54 // tentar colocar damas em todas as colunas
55 for (int i = 0; i < nDamas; i++) {
56 int j = 0;
57 // verificar se ha uma dama a atacar esta posicao
58 for (; j < novaLinha; j++)
59 if (i == damas[j] || i == damas[j] + (novaLinha - j) || i == damas[j] - (novaLinha - j))
60 break;
61 if (j == novaLinha) { // e possivel, adicionar sucessor
64 return;
65 sucessor->damas += i;
67 }
68 }
70}
71
74 if (damas.Count() + 1 == suc->damas.Count())
75 return TString().printf("d%d", suc->damas.Last() + 1);
76 return "Inv";
77}
78
79void COitoDamas::Debug(bool completo)
80{
81 if (!completo) {
82 NovaLinha();
83 for (auto dama : damas)
84 printf("d%d ", dama);
85 return;
86 }
87 for (int i = 0; i < nDamas; i++) {
88 NovaLinha();
89 for (int j = 0; j < nDamas; j++) {
90 if (damas.Count() > i && damas[i] == j)
91 printf("%2s", "♛ "); //"♛ ");
92 else
93 printf("%s", ((i + j) % 2 ? " " : "::")); // "▒▒" "::" "░░"
94 }
95 }
96
97}
98
99
101{
103 // obter o estado normalizado, para que os estados fiquem iguais a menos de operações de simetria
104 Normalizar(damas);
106 // codificar números de 4 bits
107 // (0 a 7 daria 3 bits, mas para ser múltiplo de 64 usa-se 4 bits)
108 for (int i = 0, index = 0; i < damas.Count(); i++, index += 4)
109 estado.SetBits(damas[i], index, 4);
110}
111
112// coloca em damas o estado normalizado segundo as 3 simetrias
113void COitoDamas::Normalizar(TVector<int>& damas) {
114 static int tab[MAX_DAMAS][MAX_DAMAS];
115 int peso, atual;
116 bool alterado;
118 // inicializar tabuleiro
119 for (int i = 0; i < nDamas; i++)
120 for (int j = 0; j < nDamas; j++)
121 tab[i][j] = 0;
122 for (int i = 0; i < damas.Count(); i++)
123 tab[i][damas[i]] = 1;
124 // obter o tabuleiro de menor peso, mediante as 3 simetrias
125 peso = atual = PesoVersao(tab);
126 do {
127 alterado = false;
128 for (int i = 0; i < 3; i++) {
129 Simetria(tab, i);
130 atual = PesoVersao(tab);
131 if (atual < peso) {
132 peso = atual;
133 alterado = true;
134 }
135 else
136 Simetria(tab, i); // repor
137 }
138 } while (alterado);
139 // percorridas todas as simetrias e nada é melhor, escolher esta
140 // converter para o outro formato, em que -1 é dama não existe na linha
142 damas.Reset(-1);
143 for (int i = 0; i < nDamas; i++)
144 for (int j = 0; j < nDamas; j++)
145 if (tab[i][j])
146 damas[i] = j;
147}
148
149int COitoDamas::PesoVersao(int tab[MAX_DAMAS][MAX_DAMAS]) {
150 int peso = 0;
151 for (int i = 0; i < nDamas; i++)
152 for (int j = 0; j < nDamas; j++)
153 if (tab[i][j])
154 peso += i * nDamas + j;
155 return peso;
156}
157
158void COitoDamas::Troca(int& a, int& b) {
159 int aux = a;
160 a = b;
161 b = aux;
162}
163
164// é suficiente estas 3 simetrias para simular qualquer outra
165void COitoDamas::Simetria(int tab[MAX_DAMAS][MAX_DAMAS], int eixo) {
166 if (eixo == 0) { // simetria horizontal
167 for (int i = 0; i < nDamas; i++)
168 for (int j = 0; j < nDamas / 2; j++)
169 Troca(tab[i][j], tab[i][nDamas - 1 - j]);
170 }
171 else if (eixo == 1) { // simetria vertical
172 for (int i = 0; i < nDamas / 2; i++)
173 for (int j = 0; j < nDamas; j++)
174 Troca(tab[i][j], tab[nDamas - 1 - i][j]);
175 }
176 else { // simetria diagonal
177 for (int i = 0; i < nDamas; i++)
178 for (int j = i + 1; j < nDamas; j++)
179 Troca(tab[i][j], tab[j][i]);
180 }
181}
constexpr int MAX_DAMAS
Definition OitoDamas.h:4
constexpr int MAX_DAMAS
Definition OitoDamas.h:18
Representa um estado do problema das 8 damas.
Definition OitoDamas.h:15
void Debug(bool completo=true) override
Mostra o estado no ecrã, para debug.
Definition OitoDamas.cpp:79
static int nDamas
Definition OitoDamas.h:22
void Inicializar(void)
Coloca o objecto no estado inicial da procura.
Definition OitoDamas.cpp:24
TString Acao(TProcuraConstrutiva *sucessor)
Definition OitoDamas.cpp:72
void Sucessores(TVector< TNo > &sucessores)
Coloca em sucessores a lista de estados sucessores.
Definition OitoDamas.cpp:51
~COitoDamas(void)
Definition OitoDamas.cpp:10
TVector< int > damas
Definition OitoDamas.h:21
void Gravar(void)
Definition OitoDamas.cpp:39
TProcuraConstrutiva * Duplicar(void)
Cria um objecto que é uma cópia deste.
Definition OitoDamas.cpp:14
void ResetParametros()
Inicializa os parâmetros, indicadores e instâncias.
Definition OitoDamas.cpp:45
COitoDamas(void)
Definition OitoDamas.cpp:6
void Codifica(TBits &estado)
Codifica o estado para um vetor de inteiros de 64 bits.
void SetBits(uint64_t value, int bitIndex, int bitCount)
Definition TVector.h:1385
Representa um estado no espaço de estados.
void NovaLinha(bool tudo=true)
static bool memoriaEsgotada
Flag indicando problemas de memória esgotada.
Definition TProcura.h:583
static int resultado
Resultado retornado pelo algoritmo na última execução.
Definition TProcura.h:575
static TString ficheiroInstancia
prefixo do nome ficheiro de uma instância - editado pelo utilizador Caso não seja nulo,...
Definition TProcura.h:562
static TString ficheiroGravar
prefixo do nome do ficheiro para gravar a instância para ficheiro (terá sido gerada)
Definition TProcura.h:564
static TParametro instancia
ID da instância atual, a ser utilizado em SolucaoVazia().
Definition TProcura.h:22
TString & printf(const char *fmt,...)
Definition TVector.h:1150
bool Empty() const
Definition TVector.h:1184
TVector< TString > readLines()
Definition TVector.h:1229
TString & writeLines(const TVector< TString > &lines, bool append=false)
Definition TVector.h:1248
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
virtual void Sucessores(TVector< TNo > &sucessores)
Coloca em sucessores a lista de estados sucessores.
void Inicializar(void) override
Coloca o objecto no estado inicial da procura.
void ResetParametros() override
Redefinição. Ver TProcura::ResetParametros().
virtual void Codifica(TBits &estado)
Codifica o estado para um vetor de inteiros de 64 bits.
int valor
valor do parâmetro
Definition TProcura.h:179