• Nenhum resultado encontrado

PROCEDIMENTO 8 – REPARAÇÃO.DE CAMINHO

6.2 OPERADORES

6.2.3 Construtivo Guloso Aleatório

O operador construtivo guloso aleatório gera uma solução, o caminho da nova solução é gerado em três níveis de construção sendo que os dois primeiros níveis apresentam características gulosa e aleatória e, o terceiro nível apresenta um procedimento de reparação para o caminho hamiltoniano. Como exemplo, o tabuleiro 4x4 é usado para a construção de uma solução, ver Figura 27 (a).

Primeiro, define-se a quantidade de vértices para o caminho que será construído no primeiro e segundo nível que terá característica gulosa e aleatória, esse caminho poderá apresentar entre 50 a 80% dos vértices do grafo grade G.

Segundo, define-se a quantidade de vértices para o caminho no primeiro nível e depois para o segundo nível. No exemplo, supondo um caminho com característica gulosa e aleatória (com 70% dos vértices no grafo grade G), ver Figura 27 (a), logo o caminho terá 11 vértices; nesse caso, o caminho construído no primeiro nível poderá ter 5 vértices e, no segundo nível, o caminho poderá ter o acréscimo de 6 vértices.

Terceiro, o primeiro nível constrói um vetor com caminhos cujos comprimentos são iguais a 5 vértices; no exemplo, cada caminho construído no primeiro nível iniciou no vértice 0 do grafo grade G, como mostra a Figura 27 (b). O vetor com caminhos é ordenado decrescentemente pelo valor objetivo, ver Figura 27 (c). Um total de 40% dos caminhos com piores valores objetivos são removidos do vetor, ver Figura 27 (d).

Quarto, seleciona-se aleatoriamente um caminho do vetor com caminhos de primeiro nível; no exemplo, o caminho (0-4-8-12-13) foi selecionado, ver Figura 28 (a). O segundo nível constrói um vetor com caminhos cujos comprimentos são iguais a 6 vértices; no exemplo, cada caminho construído no segundo nível iniciou no vértice 13 do grafo grade G, como mostra as Figura 28 (b) e (c). O vetor com caminhos é ordenado decrescentemente pelo valor objetivo, ver Figura 28 (d). Um total de 40% dos caminhos com piores valores objetivos são removidos do vetor, ver Figura 28 (e).

Quinto, seleciona-se aleatoriamente um caminho no vetor com caminhos de segundo nível, repara o caminho hamiltoniano e, realiza o rolamento do dado sobre o caminho construído. Na Figura 29 (a), o caminho (0-4-8-12-13-14-15-11-7-6-10) foi selecionado no vetor com caminhos de segundo nível. Na Figura 29 (b), o caminho hamiltoniano é reparado. E, na Figura 29 (c), uma solução com caminho, faces do dado sobre o caminho e somatório das faces dado é definida.

Figura 29 – Exemplo Construção Terceiro Nível.

O Procedimento 4 (construcao_gulosa_aleatoria()) tem como entrada a variável numerica (A) que define um valor porcentual para a lista de candidato restrita, a variável numerica (T) que define o tamanho dos caminhos com característica gulosa e aleatória, um grafo grade G (matriz de adjacência) e, como saída, uma solução 4(S).

As linhas 1 e 2 declaram e iniciação as variáveis numéricas (nível_1 e nível_2) para guardarem valores correspondentes ao total de vértices nos caminhos do primeiro e segundo nível. A variável (nível_2) poderá guardar um valor máximo correspondente a 80% dos vértices do grafo grade G. A variável numérica (nível_1) guardará um valor correspondente a metade dos valores da variável (nível_2).

4 A solução é representada por dois vetores de inteiros, um para o caminho, outro para as

A linha 4 declara um vetor (caminho_nivel_1) para armazenar os caminhos construídos no primeiro nível, cada elemento do vetor armazena dois tipos de informações, um para o caminho e o outro para o somatório das faces do dado desse caminho.

A linha 5 executa o procedimento (construir_caminho_nivel_1()) para construir os caminos no primeiro nível.

O laço mais externo entre as linhas de números 7 a 17 será executado até o vetor (caminho_nivel_1) ficar vazio ou a solução (S) ser construída. No pior caso, o laço executa até o vetor ficar vazio, aqui, o laço executa 50 vezes, devido o vetor apresentar no máximo esse valor. A cada iteração do laço mais externo, o procedimento (construir_caminho_nivel_2()) remove um elemento do vetor (caminho_nivel_1).

A linha 9 declara um vetor (caminho_nivel_2) para guardar os caminhos construídos no segundo nível, cada elemento do vetor também armazena dois tipos de informações, um para o caminho e outro para somatório das faces do dado desse caminho. Na linha 10, o procedimento (construir_caminho_nivel_2()) construirá os caminos do segundo nível.

O laço mais interno entre as linhas de números 12 a 16 executará até o vetor (caminho_nivel_2) ficar vazio ou a solução (S) ser construída. No pior caso, o laço executará até o vetor ficar vazio, aqui, o laço também executará 50 vezes, devido o tamanho máximo do vetor (caminho_nivel_2). E, a cada iteração do laço, o procedimento (construir_caminho_nivel_3()) remove um elemento do vetor (caminho_nivel_2).

Na linha 10, o procedimento (construir_caminho_nivel_3()) construirá uma solução (S).

Procedimento 4 – Construção gulosa aleatória. construcao_gulosa_aleatoria ( )

Entrada:

A (variável para definir o tamanho da lista de candidato restrita),

T (variável para definir o tamanho do caminho no primeiro e segundo nível), G (Grafo) Saída: S 1 nivel_2 ← |G(V)| * T 2 nivel_1 ← (nível_2) / 2 3 4 caminho_nivel_1 5 caminho_nivel_1 ← construir_caminho_nivel_1(nivel_1, A, G) 6

7 Enquanto (caminho_nivel_1 ≠ ∅ E S.caminho == ∅) faça 8

9 caminho_nivel_2

10 caminho_nivel_2 ← construir_caminho_nivel_2(caminho_nivel_1, nível_2, A, G)

11

12 Enquanto (caminho_nivel_2 ≠ ∅ E S.caminho == ∅) faça 13 14 S ← construir_caminho_nivel_3(caminho_nivel_2, G) 15 16 Fim_enquanto 17 Fim_enquanto 18 19 Retonar S

O Procedimento 5 (construir_caminho_nivel_1()) tem como entrada a vaiável numérica (nível_1), que define o tamanho dos caminhos no primeiro nível, a variável (A), que define um valor porcentual para a lista de candidato restrita, um grafo grade G (matriz de adjacência) e, como saída, um vetor (caminho_nivel_1) com os caminhos no primeiro nível.

A linha 1 declara a estrutura pilha definida na seção 5. A linha 2 declara a variável numérica (v) e inicializa com o vértice 0 (zero) do grafo grade G. A linha 3 executa o procedimento (vertices_adjacentes(), disponível na seção 4.1) para selecionar os vértices adjacentes do vértice (v). E, na linha 4, o vértice (v) e seus vizinhos (lista_v) são adicionados na pilha.

Na linha 6, a variável booleana (saída_enquanto) é declara e inicializada com valor verdadeiro. Entre as linhas de números 7 a 36, o laço executará até a condição na linha 32 ser satisfeita.

O empilhamento, entre as linhas 9 a 25, executa até a pilha atingir o tamanho igual ao valor da variável (nivel_1). A variável (nivel_1) terá no máximo um valor igual a 40% dos vértices do grafo grade G.

Na linha 10, a variável (v) armazena um vértice selecionado aleatoriamente na lista do topo da pilha; o vértice selecionado é removido, na linha 11, da lista do topo da pilha para evitar ser selecionado em iterações futuras.

Na linha 13, o procedimento (ponto_isolamento(), disponível na seção 4.2), verifica o vértice (v) como viável. Caso verdadeiro, a linha 14 armazena na lista (lista_v) os vértices adjacentes do vértice (v), a linha 15 adiciona na pilha o vértice (v) e a lista (lista_v) e, na linha 16, o procedimento (marca_grafo1(), disponível na seção 4.4.1) marca o vértice (v) no grafo grade G.

Na linha 19, o tamanho da pilha é verificado igual ao valor da variável (nível_1); caso verdadeiro, na linha 20, a estrutura solução (S) é declarada e, na linha 21, o procedimento (rolamento_dado(), disponível na seção 4.6) executa o rolamento do dado, esse procedimento tem como entrada um caminho e, como saída, uma solução (S).

Na linha 23, um elemento é adicionado no vetor (caminho_nivel_1), cada elemento adicionado no vetor (caminho_nivel_1) apresenta um caminho construído no grafo grade G e o somatório das faces.

O desempilhamento ocorre entre as linhas 27 a 30. Na linha 28, o grafo grade G é marcado com o procedimento (marca_grafo2(), disponível na seção 4.4.2). E, na linha 29, um desempilhamento acontece na pilha.

As linhas de números 32 a 34 verificam a condição de saída do laço mais externo; caso verdadeiro, a linha 33 atualiza a variável booleana (saída_enquanto) com valor falso.

Na linha 38, o vetor (caminho_nivel_1) é ordenado decrescentemente pelo somatório das faces do dado.

Na linha 40, a variável (int_corte) é declarada para definir o tamanho da lista de candidato restrita. Na linha 41, o laço executa até o limite da variável (int_corte), na linha 42, o último elemento do vetor (caminho_nivel_1) é removido. E, na linha 45, o vetor (caminho_nivel_1) é retornado.

Procedimento 5 – Construção Primeiro Nível. construir_caminho_nivel_1 ( )

Entrada:

nível_1 (variável para definir o tamanho dos caminhos no primeiro nível) A (variável para definir o tamanho da lista de candidato restrita),

G (Grafo)

Saída: caminho_nivel_1 (um vetor com os caminhos do primeiro nível) // Inicio 1 Pilha pilha 2 v ← 0 3 lista_v ← vertices_adjacentes (v, G); 4 pilha.add(v, lista_v) 5 6 saida_enquanto ← verdade

7 Enquanto (saída_enquanto == verdade) faça

9 Enquanto (pilha.topo.lista ≠ Ø E pilha.tamanho < nivel_1) faça 10 v ← seleciona_vertice_aleatorio(pilha.topo.lista)

11 pilha.topo.lista.remove(v) 12

13 Se (ponto_isolamento(v, retorna_caminho(pilha), G) == T ) faça 14 lista_v ← vertices_adjacentes (v, G);

15 pilha.add(v, lista_v)

16 marca_grafo1(G, retorna_caminho(pilha)) 17 Fim_se

18

19 Se (pilha.tamanho == nível_1) faça 20 Solucao S 21 rolamento_dado(retorna_caminho(pilha), S) 23 caminho_nivel_1.add(S.soma, S.caminho) 24 Fim_se 25 Fim_enquanto 26

27 Enquanto (pilha.topo.lista == Ø OU pilha.tamanho > nivel_1) faça 28 marca_grafo2(G, retorna_caminho(pilha)) 29 pilha.desempilha 30 Fim_enquanto 31 32 Se (caminho_nivel_1.tamanho == 50) faça 33 saída_enquanto ← falso 34 Fim_se 35 36 Fim_enquanto 37 38 ordena_decrescente (caminho_nivel_1) 39 40 int_corte ← caminho_nivel_1.tamanho * A 41 Para (i ← 1 até int_corte) faça

42 caminho_nivel_1.remove_ultimo 43 Fim_para

44

O Procedimento 6 (construir_caminho_nivel_2()) tem como entrada um vetor (caminho_nivel_1) com os caminhos de primeiro nível, a vaiável numérica (nível_2) que define o tamanho dos caminhos de segundo nível, a variável (A) que define um valor porcentual para a lista de candidato restrita, um grafo grade G (matriz de adjacência) e, como saída, um vetor (caminho_nivel_2) com os caminhos de segundo nível.

Na linha 1, a variável numérica (int_sorteio) guarda o índice selecionado aleatoriamente do vetor (caminho_nivel_1). O vetor (v_caminho), na linha 2, é declarado para guardar um caminho selecionado no vetor (caminho_nivel_1), de acordo com o valor definido pelo índice. E, na linha 3, o caminho selecionado no vetor (caminho_nivel_1) é removido.

Entre as linha de números 6 a 10, o caminho selecionado (v_caminho) é carregado na estrutura pilha. Da linha 12 em diante, o procedimento (construir_caminho_nivel_2()) executa os mesmos passos do procedimento (construir_caminho_nivel_1()).

Procedimento 6 – Construção Segundo Nível. construir_caminho_nivel_2 ( )

Entrada:

caminho_nivel_1 (vetor com caminhos de primeiro nível)

nível_2 (variável para definir o tamanho dos caminhos no segundo nível) A (variável para definir o tamanho da lista de candidato restrita),

G (Grafo)

Saída: caminho_nivel_2 (um vetor com os caminhos do primeiro nível) // Inicio

1 int_sorteio ← seleciona_aleatorio [0 - caminho_nivel_1.tamanho] 2 v_caminho ← caminho_nivel_1[int_sorteio].caminho

3 caminho_nivel_1.remove(int_sorteio) 4

5 Pilha pilha

6 Para (i ← 0 até v_caminho.tamanho) faça 7 v ← v_caminho[i] 8 lista_v ← vertices_adjacentes(v, G); 9 pilha.add(v, lista_v) 10 Fim_para 11 12 saida_enquanto ← verdade

13 Enquanto (saída_enquanto == verdade) faça 14

15 Enquanto (pilha.topo.lista ≠ Ø E pilha.tamanho < nivel_2) faça 16 v ← seleciona_vertice_aleatorio(pilha.topo.lista)

17 pilha.topo.lista.remove(v) 18

19 Se (ponto_isolamento(v, retorna_caminho(pilha)) == T ) faça 20 lista_v ← vertices_adjacentes(v, G);

21 pilha.add(v, lista_v)

22 marca_grafo1(G, retorna_caminho(pilha)) 23 Fim_se

24

25 Se (pilha.tamanho == nível_2) faça 26 Solucao s 27 rolamento_dado(retorna_caminho(pilha), s) 28 29 caminho_nivel_2.add(s.soma, s.caminho) 30 Fim_se 31 Fim_enquanto 32

33 Enquanto (pilha.topo.lista == Ø OU pilha.tamanho > nivel_1) faça 34 marca_grafo2(G, retorna_caminho(pilha)) 35 pilha.desempilha 36 Fim_enquanto 37 38 Se (caminho_nivel_2.tamanho == 50) faça 39 saída_enquanto ← falso 40 Fim_se 41 42 Fim_enquanto 43 44 ordena_decrescente (caminho_nivel_2) 45 46 int_corte ← caminho_nivel_2.tamanho * A 47 Para (i ← 1 até int_corte) faça

48 caminho_nivel_2.remove_ultimo 49 Fim_para

50

51 Retorna caminho_nivel_2

O Procedimento 7 (construir_caminho_nivel_3 ()) tem como entrada o vetor (caminho_nivel_2) com os caminhos de segundo nível, um grafo grade G (matriz de adjacência) e como saída, uma solução (S).

Na linha 1, a variável numérica (int_sorteio) guarda o índice selecionado aleatoriamente do vetor (caminho_nivel_2). O vetor (v_caminho), na linha 2, é declarado para guardar um caminho selecionado no vetor (caminho_nivel_2), de acordo com o valor definido pelo índice. E, na linha 3, o caminho selecionado no vetor (caminho_nivel_2) é removido.

Na linha 5, o grafo grade G é marcado com os vértices do caminho (v_caminho), seguindo a ideia do procedimento na seção 4.4.1. Na linha 6, o vetor de inteiros (v_terminais) guarda os vértices terminais (vértices com grau 1) presentes no grafo grade G, seguindo a ideia do procedimento na seção 4.1.

A linha 8 verifica o tamanho do vetor (v_terminais) não superior a 3 elementos. Caso verdadeiro, o grafo grade G apresenta menos de 3 vértices com grau igual a 1. Então, na linha 9, o procedimento (repara_caminho (), disponível na seção 6.2.4) é executado para finalizar a construção do caminho hamiltoniano no grafo grade G.

A linha 11 verifica a quantidade de vértices do caminho (v_caminho) igual a quantidade de vértices do grafo grade G. Se verdadeiro, na linha 12, o procedimento (rolamento_dado (), disponível na seção 4.6) é executado para fazer o rolamento do dado sobre o caminho (v_caminho). E, assim, uma solução (S) é definida com um caminho, as faces do dado sobre o caminho e o somatório das faces do dado.

Procedimento 7 – Construção Terceiro Nível. Construir_caminho_nivel_3 ( )

Entrada:

caminho_nivel_2 (vetor com caminhos de segundo nível) G (Grafo)

Saída: S //Inicio

1 int_sorteio ← seleciona_aleatorio [0 - caminho_nivel_2.tamanho] 2 v_caminho ← caminho_nivel_2[int_sorteio].caminho 3 caminho_nivel_2.remove(int_sorteio) 4 5 marca_caminho_no_grafo(v_caminho, G) 6 v_terminais ← localiza_vertices_terminais (G) 7 8 Se (vertices_terminais.tamanho < 3) faça

9 v_caminho ← repara_caminho(v_caminho, v_terminais, G) 10 11 Se (v_caminho.tamanho == |G(V)|) faça 12 rolamento_dado(v_caminho, S) 13 Fim_se 14 15 Fim_se 16 17 Retornar S

Documentos relacionados