• Nenhum resultado encontrado

PROCEDIMENTO 8 – REPARAÇÃO.DE CAMINHO

4.7 ATUALIZAR O VETOR DE SOLUÇÕES

O “Procedimento Atualizar o Vetor de Soluções” tem como entrada o vetor de soluções (v_solucao) e a nova solução construída (nova_s) e como saída, o vetor de soluções atualizado. O procedimento realiza uma das três regras para atualização:

1. Verificar se o vetor de soluções (v_solucao) está vazio; caso verdade, a nova solução (nova_s) é adicionada ao vetor e o procedimento finalizado; 2. Verificar se o valor objetivo da nova solução (nova_s) é igual aos valores

solução (nova_s) é adicionada ao vetor (v_solucao) e o procedimento finalizado;

3. Verificar se o valor objetivo da nova solução (nova_s) é melhor que os valores objetivos das soluções do vetor (v_solucao); caso verdade, as soluções do vetor (v_solucao) são removidas, a nova solução é adicionada ao vetor e o procedimento finalizado.

5 ABORDAGEM EXATA

O algoritmo exato para o problema Hiker Dice é um Backtracking usando uma estrutura pilha. Cada elemento da pilha apresenta dois compartimentos para guardar informação do caminho em construção. A Figura 20 exemplifica um elemento da pilha. O primeiro, guarda um vértice referente ao caminho em construção no tabuleiro (parte em amarelo); o segundo, guarda uma lista referente às ramificações (vizinhos) do vértice escolhido (parte em azul).

Figura 20 - Elemento da estrutura pilha.

Passos do algoritmo:

1. Adicionar como primeiro elemento na pilha um vértice do grafo que represente o início do caminho na parte amarela e suas ramificações (vizinhos), na parte em azul. Depois, serão realizados os passos seguintes até a pilha ficar vazia;

2. Verificar se a pilha não está vazia para continuar o procedimento no passo 3. Se estiver, finalizar procedimento no passo 9;

3. Verificar se a lista do topo da pilha é maior que zero. Se for o caso, deve- se fazer o passo 4; caso contrário, o desempilhamento (passo 8);

4. Selecionar um vértice presente na lista do topo da pilha; depois, marcá-lo como vizitado;

5. Verificar se o vértice selecionado, no passo 4, não pertence ao caminho que está sendo construído, não cause isolamentos de pontos no grafo e mantenha o controle de pontos terminais (ver seção 4);

6. Se verdadeiro, o passo 5, adicionar como próximo elemento da pilha o vértice selecionado no passo 4 na parte amarela, e seus vizinho(s) na parte azul;

7. Verificar se a parte amarela da pilha já apresenta um caminho hamiltoniano no grafo. Em caso verdadeiro, construir uma solução com o rolamento do dado no caminho construído;

8. Desempilhar um elemento na pilha; depois, continua no passo 2; 9. Finalizar execução.

Supondo que o caminho comece na posição 0 (zero) do grafo da Figura 21 (a), tem-se, a parti desse vértice, as opções de ir para a posição 1 e 3. Então, adicionamos o primeiro elemento na pilha, o vértice 0 (zero) na parte amarela e os vértices 1 e 3 na parte em azul, como mostra a Figura 21 (b).

Em seguida, o algoritmo adiciona o segundo elemento. O algoritmo verifica se a lista do topo da pilha, como mostra a Figura 21 (b), não está vazia; se verdadeiro, o primeiro elemento da lista é selecionado, o vértice 1, e obedecendo à condição de viabilidade (ver seção 4) é adicionado na parte amarela da pilha e seus vizinhos, os vértices 2 e 4, serão adicionados na parte em azul, como mostra a Figura 21 (c).

O empilhamento na estrutura será realizado até o algoritmo não conseguir adicionar mais elementos na pilha, como mostra a Figura 21 (d), nesse momento a parte amarela da pilha define um Caminho Hamiltoniano. Como a lista do topo da pilha está vazia o algoritmo começa a fazer alguns desempilhamentos até encontrar o primeiro elemento na pilha cuja lista não seja vazia.

Na Figura 21 (e), os elementos da pilha selecionados em vermelhos são todos removidos no desempilhamento por terem listas vazias; depois, o empilhamento começa novamente ao encontrar um elemento na pilha cuja lista não seja vazia.

O caminho (definido pela parte amarela da estrutura pilha no exemplo da Figura 21 (d)) é exemplificado em uma árvore de estado, na Figura 21 (f). As aresta em negrito definem o direcionamento do caminho, as arestas tracejadas definem as opções de direcionamento de outros possíveis caminhos.

Figura 21 – Grafo Grade 3 x 3 (a); Construção do caminho (b), (c), (d) e (e); Exemplo de Árvore de Estado (f).

O Algoritmo 1 tem como entrada um Grafo Grade G que representa o tabuleiro e como saída, apresenta uma ou mais de uma solução3. A linha 1 declara

uma estrutura tipo pilha. A linha 2 define o primeiro vértice do grafo que será adicionado ao caminho, nesse caso o vértice 0 (zero). A linha 3 executa um procedimento para retornar a lista de vértices adjacentes ao vértice (v) (procedimento disponível na seção 4.3). A linha 4 adiciona na pilha o vértice (v) no primeiro compartimento e a lista com vértices adjacentes (lista_v), no segundo compartimento.

3 Uma solução é representada por dois vetores de inteiros, um para o caminho, outro para

As linhas de números 5 a 25 farão a busca de todas as soluções para o grafo que está sendo analisado. A linha 5 dará continuidade a busca das soluções se a pilha não estiver vazia. A linha 6, verificará a condição de empilhamento e desempilhamento. O empilhamento será feito entre as linhas 7 e 13; e o desempilhamento, entre as linhas 20 e 23.

Caso a condição de empilhamento seja verdadeira, a linha 7 executa a seleção do primeiro vértice na lista do topo da pilha. A linha 8 remove da lista do topo da pilha o vértice selecionado, impede a seleção de vértices repetidos em iterações futuras. A linha 9 verifica as condições de viabilidade do vértice selecionado (disponível na seção 4). A linha 10 retorna os vizinhos do vértice (v) e a linha 11, adiciona o próximo elemento na pilha. Na linha 12, o grafo é marcado com o procedimento (descrito na seção 4.4.1). Nas linhas 9, 12, 16 e 21, o procedimento (retorna_caminho( )) retorna um vetor de inteiros correspondente ao caminho definido pela parte amarela da pilha.

As linhas de números 14 a 18 farão a construção de uma solução. A linha 14 verifica se o tamanho da pilha é igual a quantidade vértices do grafo; caso verdade, a linha16 executa o procedimento (rolamento_dado(), disponível na seção 4.6) para construir uma solução com base no caminho. A linha 16 executa o procedimento (atualiza_solucoes(), disponível na seção 4.7) para atualizar o vetor de soluções.

E, as linhas de números 20 a 23 farão o desempilhamento. Na linha 21, o grafo é marco com o procedimento da seção 4.4.2.

Algoritmo 1 – Algoritmo Exato. Exato_HikerDice ( )

Entrada: G(V, A)

Saída: v_solucao (vetor de soluções) 0 // Inicio 1 Pilha pilha 2 v ← 0 3 lista_v ← vertices_adjacentes (v, G) 4 pilha.add(0, lista_v) 5 Equanto(pilha ≠ ∅) faça 6 Se (pilha.topo.lista > 0) então 7 v ← pilha.topo.lista.ponto_frente 8 pilha.topo.ponto_frente_remove 9 Se (ponto_isolamento (v, retorna_caminho(pilha), G) == T e vertices_terminais(v, retorna_caminho(pilha), G) == T) 10 lista_v ← vertices_adjacentes (v, G); 11 pilha.add(v, lista_v) 12 marca_grafo1(G, retorna_caminho(pilha)) 13 Fim_se 14 Se (pilha.tamanho == |V(G)|) faça 15 Solucao nova_s 16 nova_s ← rolamento_dado(retorna_caminho(pilha)) 17 v_solucao ← atualizar_solucoes(v_solucao, nova_s) 18 Fim_se 19 Contrario 20 Se (pilha ≠ ∅)) faça 21 marca_grafo2(G, retorna_caminho(pilha)) 22 pilha.desempilhar_elemento 23 Fim_se 24 Fim_se 25 Fim_enquanto

6 ABORDAGEM HEURÍSTICA

Na seção 6.1, serão apresentados os Algoritmos Heurísticos e na seção 6.2, os operadores propostos para o problema Hiker Dice.

6.1 ALGORITMOS ADAPTADOS COM OS OPERADORES PROPOSTOS

Documentos relacionados