Sub local_search_shift(ByRef M() As Long, ByRef v_sol() As Integer, ByRef z As Long)
' Local search usando o operador de vizinhança
' shift (reinsere um ponto em outro local (fazendo o shift de todos os outros)
Dim melhora As Boolean
melhora = True
Do While melhora = True
' GERAR OS VIZINHOS
melhora = gera_vizinhos_shift(M, v_sol, z)
Loop
End Sub
Function gera_vizinhos_shift(ByRef M() As Long, ByRef v_sol() As Integer, ByRef z As Long) As Boolean
' Gerar os vizinhos pelo shift, ate o
' momento em que um vizinho tenha valor de z
' melhor do que o z do argumento
Dim i As Integer
Dim j As Integer
Dim custo_shift As Long
Dim melhorou As Boolean
For i = 2 To UBound(v_sol) ' elemento a ser reinserido
For j = 0 To i - 2 ' posição da reinserção
custo_shift = shift(M, v_sol, i, j)
If custo_shift < z Then
' Faz o shift no vetor e retorna o resultado
z = custo_shift
Dim aux As Integer
aux = v_sol(i)
Dim index As Integer
For index = i To j + 1 Step -1
v_sol(index) = v_sol(index - 1)
Next index
v_sol(j) = aux
melhorou = True
gera_vizinhos_shift = melhorou
Exit Function
End If
Next j
Next i
melhorou = False
gera_vizinhos_shift = melhorou
End Function
Function shift(ByRef M() As Long, ByRef v_sol() As Integer, index_antigo As Integer, index_novo As Integer) As Long
' faz a inserção do elemento de index_antigo na posicao index_novo,
' realocando os outros elementos para direita.
' Sempre index_antigo > index_novo
Dim v_copia() As Integer
v_copia = v_sol
Dim i As Integer
Dim aux As Integer
aux = v_copia(index_antigo)
' Aloca os elementos para a direita
For i = index_antigo To index_novo + 1 Step -1
v_copia(i) = v_copia(i - 1)
Next i
' Reinsere o elemento na nova posição
v_copia(index_novo) = aux
shift = calcula_custo(v_copia, M)
End Function