• Nenhum resultado encontrado

Recombinacao ( )

Entrada: S1 (Solução 1), S2 (Solução 2), G (grafo em matriz de adjacência) Saída: Sr (nova solução)

//inicio

1 v_caminho

2 tamanho ← S1.caminho_tamanho * 0,5 3 Para (i ← 0; i < tamanho; i++) faça 4 v_caminho.add(S1.caminho[i]) 5 Fim_para

6

7 Para (i ← v_caminho.tamanho; i > 0; --i) faça 8 v ← v_caminho[i]

9 s ← v_sucessor(v, S2)

10 Se (teste_s (v_caminho, s) == T) faça 11 Sair do laço 12 Contrario 13 v_caminho.remove_ultimo_vertice 14 Fim_se 15 Fim_para 16 17 Indice 18 ponto_r ← v_caminho.ultimo

19 Para (i ← 0; i < S2.caminho_tamanho; ++i) faça 20 Se (S2.caminho[i] == ponto_r) faça

21 indice ← i + 1 22 Sair do laço 23 Fim_se

24 Fim_para 25

26 Para (i ← indice; i < S2.caminho_tamanho; ++i) faça 27 v ← S2.caminho[i]

28 Se(teste_s (v_caminho, v) == T) faça 29 v_caminho.add(v) 30 Contrario 31 Sair do laço 32 Fim_se 33 Fim_para 34 35 marca_caminho_grafo(v_caminho, G) 36 v_terminais ← vertices_terminais (G) 37 38 Se (v_terminais.tamanho <= 2) faça

39 v_caminho ← repara_caminho(v_caminho, v_terminais, G) 40 Fim_se 41 42 Se (v_caminho.tamanho == |G(V)|) faça 43 rolamento_dado(v_caminho, Sr) 44 Fim_se 45 46 Retornar Sr

As linhas 26 a 33 armazenam no vetor de inteiros (v_caminho) o material genético do caminho da solução (S2). Na linha 26, o laço executa a partir da variável (indice) até a última posição do caminho na solução (S2); ou, encontrar um vértice no caminho da solução (S2) que não pode ser adicionado ao caminho (v_caminho). Na linha 27, a variável (v) armazena o vértice do caminho na solução (S2).

Na linha 28, o teste realizado pelo procedimento (teste_s()) será verdadeiro quando obedecer duas condições: primeira, o vértice (v) ainda “não existe” no caminho (v_caminho); segundo, o vértice (v) quando unido ao caminho (v_caminho) não se apresentará como “ponto de isolamento”. Se verdadeiro, o vértice (v) é adicionado ao caminho (v_caminho).

A linha 35 executa o procedimento (marca_caminho_grafo()) para marcar o grafo grade G com os vértices do caminho (v_caminho), seguindo a ideia apresentada no procedimento da seção 4.4.1. Na linha 36, um vetor do tipo inteiro (v_terminais) recebe os vértices terminais (vértices com grau 1) que possam surgir no grafo grade G.

As linhas de números 38 a 40 fazem a reparação do caminho (v_caminho) com ajuda do procedimento (repara_caminho()). Na linha 38, se o tamanho do vetor (v_terminais) é menor ou igual a 2, então o grafo grade G apresenta no máximo dois vértices terminais e assim, na linha 39, o procedimento (repara_caminho(), disponível na seção 6.2.4) será executado.

A linha 42 verifica o caminho (v_caminho) com mesma quantidade de vértices do grafo grade G; caso verdadeiro, a linha 43 executa o procedimento (rolamento_dado (), disponível na seção 4.6), para fazer o rolamento do dado sobre o caminho (v_caminho). E, a linha 46 retorna a solução (Sr) construída por recombinação.

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.

Documentos relacionados