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.Count(0);
29 // 4 bits por dama, com 40 damas no máximo dá 3 inteiros de 64 bits
30 tamanhoCodificado = (nDamas - 1) * 4 / 64 + 1;
31}
32
38
40{
41 int novaLinha = damas.Count();
42 // tentar colocar damas em todas as colunas
43 for (int i = 0; i < nDamas; i++) {
44 int j = 0;
45 // verificar se ha uma dama a atacar esta posicao
46 for (; j < novaLinha; j++)
47 if (i == damas[j] || i == damas[j] + (novaLinha - j) || i == damas[j] - (novaLinha - j))
48 break;
49 if (j == novaLinha) { // e possivel, adicionar sucessor
52 return;
53 sucessor->damas.Add(i);
55 }
56 }
58}
59
60const char* COitoDamas::Acao(TProcuraConstrutiva* sucessor) {
61 static char str[20];
63 if (damas.Count() + 1 == suc->damas.Count()) {
64 sprintf(str, "d%d", suc->damas.Last() + 1);
65 return str;
66 }
67 return "Inv";
68}
69
71{
72 for (int i = 0; i < nDamas; i++) {
73 NovaLinha();
74 for (int j = 0; j < nDamas; j++) {
75 int cor = ((i + j) % 2 ? ' ' : ':');
76 if (damas.Count() > i && damas[i] == j)
77 printf("%c%c", '#', '#');
78 else
79 printf("%c%c", cor, cor);
80 }
81 }
82}
83
84
86{
88 // obter o estado normalizado, para que os estados fiquem iguais a menos de operações de simetria
89 Normalizar(damas);
91 // codificar números de 4 bits
92 // (0 a 7 daria 3 bits, mas para ser múltiplo de 64 usa-se 4 bits)
93 for (int i = 0, index = 0; i < damas.Count(); i++, index += 4)
94 estado[index >> 6] |= (uint64_t)damas[i] << (index & 63);
95}
96
97// coloca em damas o estado normalizado segundo as 3 simetrias
98void COitoDamas::Normalizar(TVector<int>& damas) {
99 static int tab[MAX_DAMAS][MAX_DAMAS];
100 int peso, atual;
101 bool alterado;
103 // inicializar tabuleiro
104 for (int i = 0; i < nDamas; i++)
105 for (int j = 0; j < nDamas; j++)
106 tab[i][j] = 0;
107 for (int i = 0; i < damas.Count(); i++)
108 tab[i][damas[i]] = 1;
109 // obter o tabuleiro de menor peso, mediante as 3 simetrias
110 peso = atual = PesoVersao(tab);
111 do {
112 alterado = false;
113 for (int i = 0; i < 3; i++) {
114 Simetria(tab, i);
115 atual = PesoVersao(tab);
116 if (atual < peso) {
117 peso = atual;
118 alterado = true;
119 }
120 else
121 Simetria(tab, i); // repor
122 }
123 } while (alterado);
124 // percorridas todas as simetrias e nada é melhor, escolher esta
125 // converter para o outro formato, em que -1 é dama não existe na linha
127 damas.Reset(-1);
128 for (int i = 0; i < nDamas; i++)
129 for (int j = 0; j < nDamas; j++)
130 if (tab[i][j])
131 damas[i] = j;
132}
133
134int COitoDamas::PesoVersao(int tab[MAX_DAMAS][MAX_DAMAS]) {
135 int peso = 0;
136 for (int i = 0; i < nDamas; i++)
137 for (int j = 0; j < nDamas; j++)
138 if (tab[i][j])
139 peso += i * nDamas + j;
140 return peso;
141}
142
143void COitoDamas::Troca(int& a, int& b) {
144 int aux = a;
145 a = b;
146 b = aux;
147}
148
149// é suficiente estas 3 simetrias para simular qualquer outra
150void COitoDamas::Simetria(int tab[MAX_DAMAS][MAX_DAMAS], int eixo) {
151 if (eixo == 0) { // simetria horizontal
152 for (int i = 0; i < nDamas; i++)
153 for (int j = 0; j < nDamas / 2; j++)
154 Troca(tab[i][j], tab[i][nDamas - 1 - j]);
155 }
156 else if (eixo == 1) { // simetria vertical
157 for (int i = 0; i < nDamas / 2; i++)
158 for (int j = 0; j < nDamas; j++)
159 Troca(tab[i][j], tab[nDamas - 1 - i][j]);
160 }
161 else { // simetria diagonal
162 for (int i = 0; i < nDamas; i++)
163 for (int j = i + 1; j < nDamas; j++)
164 Troca(tab[i][j], tab[j][i]);
165 }
166}
#define MAX_DAMAS
Definition OitoDamas.h:4
#define MAX_DAMAS
Definition OitoDamas.h:16
#define OBJETO_HASHTABLE
Representa um estado do problema das 8 damas.
Definition OitoDamas.h:15
void Codifica(uint64_t estado[OBJETO_HASHTABLE])
Codifica o estado para um vetor de inteiros de 64 bits.
Definition OitoDamas.cpp:85
const char * Acao(TProcuraConstrutiva *sucessor)
Definition OitoDamas.cpp:60
static int nDamas
Definition OitoDamas.h:22
void Inicializar(void)
Coloca o objecto no estado inicial da procura.
Definition OitoDamas.cpp:24
void Debug(void)
Mostra o estado no ecrã, para debug.
Definition OitoDamas.cpp:70
void Sucessores(TVector< TNo > &sucessores)
Coloca em sucessores a lista de estados sucessores.
Definition OitoDamas.cpp:39
~COitoDamas(void)
Definition OitoDamas.cpp:10
TVector< int > damas
Definition OitoDamas.h:21
TProcuraConstrutiva * Duplicar(void)
Cria um objecto que é uma cópia deste.
Definition OitoDamas.cpp:14
void ResetParametros()
Inicializa os parametros, indicadores e instâncias.
Definition OitoDamas.cpp:33
COitoDamas(void)
Definition OitoDamas.cpp:6
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:467
static int resultado
Resultado retornado pelo algoritmo na última execução.
Definition TProcura.h:459
static TParametro instancia
ID da instância atual, a ser utilizado em SolucaoVazia().
Definition TProcura.h:21
TVector< Item > & Reset(Item const &i)
Preenche todo o vetor com um mesmo valor.
Definition TVector.h:726
int Count() const
Definition TVector.h:160
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(uint64_t estado[OBJETO_HASHTABLE])
Codifica o estado para um vetor de inteiros de 64 bits.
static int tamanhoCodificado
Número de inteiros de 64 bits utilizados para codificar um objeto (≤ OBJETO_HASHTABLE).
int valor
valor do parametro
Definition TProcura.h:114