Vous êtes sur la page 1sur 11

Dividir e Conquistar

Resoluo do problema do tabuleiro defeituoso


Aldo Pires 1402225;
Jorge Costa 1402247;
Samuel Lima 1402607.
Trabalho para a unidade curricular Heursticas Modernas
Mestrado em Tecnologias e Sistemas Informticos Web Universidade Aberta
13/05/2015

ndice
Introduo ..................................................................................................................................... 1
A abordagem de dividir e conquistar ............................................................................................ 1
Problema do tabuleiro defeituoso.................................................................................................. 3
Desenvolvimento do algoritmo ..................................................................................................... 7
Concluso .................................................................................................................................... 11

Introduo
Muitas vezes deparamos com problemas aparentemente de difcil resoluo, uma boa forma de
as solucionar dividindo em subproblemas mais simples, resolver os subproblemas e juntar as
solues obtendo a soluo do problema inicial, esta tcnica e conhecida por Dividir e conquistar.
Com este trabalho pretendemos, aplicar esta tcnica Dividir e Conquistar na resoluo do
problema do tabuleiro defeituoso.
Comeamos por fazer uma abordagem geral sobre o algoritmo, aplicando a um exemplo de fcil
compreenso, seguidamente fizemos o enquadramento do problema do tabuleiro defeituoso,
depois passamos a resoluo do problema aplicando o algoritmo Dividir e Conquistar,
seguidamente abordamos uma soluo de implementao do algoritmo.

A abordagem de dividir e conquistar


Para uma instncia de problema P de tamanho n, se n for pequeno, o problema pode ser resolvido
diretamente, caso contrario, o problema pode ser dividida em sub-instcias menores
independentes uns dos outros at que as sub-instcias sejam trivialmente resolveis, resolve-se as

sub-intncias de P recursivamente e combina as suas solues de modo a obter a soluo do


problema inicial P seja obtido.
A resoluo de um problema segundo este mtodo feito em trs fases:
Diviso: o problema maior dividido em problemas menores e os problemas menores
obtidos so novamente divididos sucessivamente de forma recursiva.
Conquista: o resultado do problema calculado quando o problema pequeno o suficiente.
Combinao: o resultado dos problemas menores so combinados at que seja obtida a
soluo do problema maior.
Este mtodo implementado em algoritmos que utilizem a metodologia Top Down, onde a
gerao dos subproblemas feita de cima para baixo.
Um exemplo para ilustrar o uso dessa tcnica o algoritmo de ordenao de um vetor por
intercalao (MergeSort).
Neste caso temos que ordenar um vetor de tamanho n.
Dividir: Dividimos o vetor de tamanho n em dois sub-vetores de tamanho [n/2]
Conquista: Resolvemos o problema de ordenao de forma recursiva para estes dois subvetores.
Combinao: Com os dois sub-vetores ordenados, construmos um vetor de tamanho n
ordenado.

MergeSort (A,p,r)
1: if p < r then
2: q = (p + r)/2

// Dividir o vetor no meio n = (p+r), n/2 = (p+r)/2

3: Mergesort(A,p,q)

// Ordenar o primeira metade recursivamente

4: Mergesort(A, q + 1,r)

// Ordenar a segunda metade recursivamente

5: Merge(A,p,q,r)

// Intercalar as duas metades

Problema do tabuleiro defeituoso


Consideremos um tabuleiro composto por quadrados, semelhantes ao de xadrez, de tamanho NN
quadrados, em que uma qualquer dessas cassas removida e passamos a chamar o tabuleiro de
defeituoso.

Figura 1- Tabuleiro de 2kx2k para k=3


Sendo que o tamanho dos lados do tabuleiro seja N: N=2k com k 1 pretende-se que o tabuleiro
defeituoso seja preenchido com peas em formato de L, designados de triominos, que ocupam
trs casas sendo a orientao irrelevante.

Figura 2-Triominos com as suas quatros possveis representaes


Para a resoluo do problema em casos em que k=1 ou mesmo k=2 pode ser resolvido
rapidamente sem muito esforo, como podemos ver na figura 3.

Figura 3-Tabuleiro 2x2 e 4x4


Com o aumento da complexidade do problema pode ficar difcil resolver o problema sem seguir
uma metodologia de apoio na sua resoluo, sendo que podemos utilizar dividir para conquistar
como mtodo de resoluo.
Considerando o problema do tabuleiro da figura 1, tabuleiro de 8x8, podemos dividir o problema
e quatro sub-problemas menores do mesmo tamanho. Onde ficamos agora com o tabuleiro
dividido em quatro tabuleiros menores de tamanho 2k-1 x 2k-1 como mostra a figura 4.

Figura 4- Diviso do tabuleiro 8x8 em quatro de 4x4


Como podemos ver ficamos com um tabuleiro defeituoso e os outros trs sem defeito e o prximo
passo ser torna-los defeituosos, desenhado um triomino na parte central conforme mostra a
figura-5.

Figura 5-Desenho do triomino central


Repetimos o mesmo processo para todos os tabuleiros de tamanho 4x4, ficando agora com 16
tabuleiros de 2x2, figura 6 e utilizando a mesma estratgia para converte-los em defeituosos figura
7.

Figura 6

Figura 7

De maneira que podemos observar, que ficamos agora perante 16 pequenos problemas de fcil
resoluo. Obtendo uma soluo global (figura 8) do problema maior proposto inicialmente.

Figura 8
O algoritmo para resoluo do problema do tabuleiro defeituoso pode ser representado pelo
fluxograma da figura 9.

Figura 9-Fluxograma resoluo do problema tabuleiro defeituoso

Para definio das reas do problema supomos que o problema seja um tabuleiro de tamanho J
colunas e I linhas onde inicialmente I=J=N=2k. Sendo assim temos valores de I linhas e J colunas
variando entre 1 e N.

Figura 10
A partir desses limites para a efetuar a diviso do problema inicial e quatro sub-problemas
menores, basta dividir as linhas e as colunas em duas partes iguais, conforme est ilustrada na
figura 10. Feita esta diviso obteremos quatro sub-problemas Q1, Q2, Q3 e Q4 delimitados pelos
valores da tabela 1.
P1

P2

Q1

Imin

Jmin

Imax/2

Jmax/2

Q2

Imin

Jmax/2+1

Imax/2

Jmax

Q3

Imax/2+1

Jmin

Imax

Jmax/2

Q4

Imax/2+1

Jmax/2+1

Imax

Jmax

Tabela 1

J com estes limites estabelecidos, para marcar o triomino central, primeiro verifica qua dos subproblemas ficou com o ponto defeituoso de seguida transforma-mos os restantes em tabuleiros
defeituosos, seguindo a seguinte lgica:

Q2

Imax/2

Jmax/2+1

Q3

Imax/2+1

Jmax/2

Q4

Imax/2+1

Jmax/2+1

PONTO NO Q1

TRIOMINO

Tabela 2-Ponto No Q1

TRIOMINO

Q1

Imax/2

Jmax/2

TRIOMINO

Q3

Imax/2+1

Jmax/2

Q4

Imax/2+1

Jmax/2+1

Tabela 3-PONTO NO Q2

Q1

Imax/2

Jmax/2

Q2

Imax/2

Jmax/2+1

Q4

Imax/2+1

Jmax/2+1

PONTO NO Q3

PONTO NO Q2

Tabela 4- Ponto No Q3

Q1

Imax/2

Jmax/2

Q2

Imax/2

Jmax/2+1

Q3

Imax/2+1

Jmax/2

PONTO NO Q4

TRIOMINO

Tabela 5-Ponto No Q4

Desenvolvimento do algoritmo
O programa possui um menu com 4 opes (figura 11), a primeira recebe o parmetro K que
define o tamanho do tabuleiro, a segunda opo a opo de debugging que quando est ativo
nos mostra os passos do preenchimento da matriz e a opo de Resultado que d inicio ao calculo
e exibio da matriz na tela.

Figura 11- Menu

Resultado

Figura 12
Para isso criamos uma classe ChessBoard, onde foi necessrio trs atributos: N que o tamanho
do tabuleiro, debug que nos avisa se para fazer o debug e a Matriz (tabuleiro) que um vector
de vector para inteiros que conforme o valor do atributo a K ser definido o tamanho do vector.

Figura 13
Temos o mtodo dividirConquistar que recursivamente vai dividindo o tabuleiro em quatro partes
iguais at o problema for trivialmente resolvel.
void ChessBoard::dividirConquistar(int iMin,int iMax,int jMin,int jMax,int posicao){
/* verifica se a soluo trivialmente resolvel */
if((iMax-iMin)==1){ /* se for verdade porque a matrix j de tamanho 2x2 */
/* preenche todas as clulas a volta do triomino com o valor do parmetro posicao */
for(int i=iMin-1;i<iMax;i++)

for(int j=jMin-1;j<jMax;j++)
if(matriz[i][j]==0) matriz[i][j]=posicao;
if(debug == 1) imprime(); /* impime se o debugin estiver activo*/
return ;
}
// caso ainda for possvel a diviso ento verificado a clula que est preenchida e feito o
preenchimento do triomino com metodo marcaTriomino
//marca o triominio central
marcaTriomino( iMin, iMax, jMin, jMax,verificaPonto( iMin, iMax, jMin, jMax));

//divide o problema e quatro sub-problemas


dividirConquistar(iMin,(iMin-1+iMax)/2,jMin,(jMin-1+jMax)/2,1);
dividirConquistar(iMin,(iMin-1+iMax)/2,(jMin-1+jMax)/2+1,jMax,2);
dividirConquistar((iMin-1+iMax)/2+1,iMax,jMin,(jMin-1+jMax)/2,3);
dividirConquistar((iMin-1+iMax)/2+1,iMax,(jMin-1+jMax)/2+1,jMax,4);

return;

O mtodo

marcaTriomino recebe como parmetro os limites da nossa matriz e tambm o

retorno da funo verificaPonto que nos d o quadrante em que a clula esta preenchida, faz a
diviso da matriz em 4 quadrantes e preenche o triomino como nos mostra a seguir

switch(posicaoPonto){
case 1:
matriz[(iMin-1+iMax)/2-1][(jMin-1+jMax)/2]=trioCont;//Q2
matriz[(iMin-1+iMax)/2][(jMin-1+jMax)/2-1]=trioCont;//Q3
matriz[(iMin-1+iMax)/2][(jMin-1+jMax)/2]=trioCont;//Q4
break;

case 2:
matriz[(iMin-1+iMax)/2-1][(jMin-1+jMax)/2-1]=trioCont;//Q1
matriz[(iMin-1+iMax)/2][(jMin-1+jMax)/2-1]=trioCont;//Q3
matriz[(iMin-1+iMax)/2][(jMin-1+jMax)/2]=trioCont;//Q4
break;

case 3:
matriz[(iMin-1+iMax)/2-1][(jMin-1+jMax)/2-1]=trioCont;//Q1
matriz[(iMin-1+iMax)/2-1][(jMin-1+jMax)/2]=trioCont;//Q2
matriz[(iMin-1+iMax)/2][(jMin-1+jMax)/2]=trioCont;//Q4
break;

case 4:
matriz[(iMin-1+iMax)/2-1][(jMin-1+jMax)/2-1]=trioCont;//Q1
matriz[(iMin-1+iMax)/2-1][(jMin-1+jMax)/2]=trioCont;//Q2
matriz[(iMin-1+iMax)/2][(jMin-1+jMax)/2-1]=trioCont;//Q3
break;
}
O programa inicializa toda a matriz a 0 e faz o preenchimento da clula aleatoriamente com -1
com mtodo - void solucaoLimpa(int k);
O cdigo vai dividindo a matriz sempre em quatro partes iguais at chegar a de 2x2
automaticamente vai preenchendo os triominos como nos mostra a figura 14.

Figura 14

Concluso
O presente trabalho pretendeu entender a importncia do uso de tcnicas heursticas na
implementao de algoritmos para resoluo de problemas computacionais complexos. Porem
um algoritmo s eficiente se houver uma utilizao otimizada dos recursos computacionais na
resoluo de um determinado problema.
Conclumos que o algoritmo dividir e conquistar, demonstrou ser uma boa soluo na resoluo
do problema do tabuleiro defeituoso e com a sua devida implementao e otimizao pode-se
obter bons resultados.

Bibliografia
Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest e Clifford Stein - Algoritmos: teoria
e prtica, traduo da 2 edio [americana], Vandenberg D. de Souza, Ed. Campus, 2002. ISBN
85-352-0926-3.

Vous aimerez peut-être aussi