SAUDAÇÕES!

Seja bem vindo à página do professor Pedro Albuquerque. Para saber mais sobre meu currículo, disciplinas ministradas e interesses de pesquisa, navegue no menu disponível no topo da página.

segunda-feira, 20 de novembro de 2017

Usando a função DEoptim em paralelo.


Um dos pacotes mais interessantes para realizar otimização é o pacote DEoptim. Essa abordagem permite a otimização de funções dos mais diversos tipos de uma maneira fácil.

Entretanto, por usar Otimização Evolucionária o processo de otimização pode ser lento, caso utilize-se muitas populações, iterações ou níveis tolerância extremos.

Aqui mostrarei como usar a opção parallelType da função DEoptim para que esse processo seja acelerado por meio da programação em paralelo.

Considere a seguinte função com múltiplos máximos e mínimos locais:

f<-function(x,y){
  res<-(268/((3*x+18)^2+(3*y+7)^2+(18+7)))-(2*(268)/((3*x-21)^2+(3*y+21)^2+(21+21)))-(3*(268)/((3*x+18)^2+(3*y-21)^2+(18+21)))+(4*(268)/((3*x-21)^2+(3*y-7)^2+(21+7))) 
  return(res)
}
Podemos fazer o gráfico dessa função através do seguinte bloco de comandos:
#Chama a biblioteca
library(plot3D)
#Cria a grade de valores na função
z<-f(M[,"x"], M[,"y"])
#Faz o gráfico
persp3D(z = z, x = M[,"x"], y = M[,"y"],
        expand = 0.3, main = "Função complicada", facets = FALSE, scale = FALSE,
        clab = "Valor da função",zlab="Valor", colkey = list(side = 1, length = 0.5))
O próximo passo para realizar a otimização é escrever a função no formato adequado para o uso do método DEoptim. Para isso, basta trocar o argumento da função que ao invés de serem dois parâmetros, será agora um vetor contendo esses dois argumentos, em outras palavras:
fEval<-function(parms){
  x<-parms[1]
  y<-parms[2]
  res<-(268/((3*x+18)^2+(3*y+7)^2+(18+7)))-(2*(268)/((3*x-21)^2+(3*y+21)^2+(21+21)))-(3*(268)/((3*x+18)^2+(3*y-21)^2+(18+21)))+(4*(268)/((3*x-21)^2+(3*y-7)^2+(21+7))) 
  return(res)
}
Note que só as três primeiras linhas foram alteradas. A seguir, precisamos configurar os nossos clusters para que a função possa ser otimizada em paralelo, a função busca pelo menor valor da função:
#Chama o pacote DEoptim e doSNOW
library(DEoptim)
library(doSNOW)
#Guarda o número de clusters disponíveis
numSlaves<- detectCores()
#Cria os clusters
cl <− makeCluster(numSlaves) 
#Passa todas as bibliotecas que são usadas para o cálculo da função
#clusterEvalQ(cl , library(pracma, ... ))
#Passa todos os objetos necessários para o cômputo da função
#clusterExport(cl , ... ) 
#Registra os clusters
registerDoSNOW (cl)
#Realiza a otimização
outDEoptim <− DEoptim (fEval, c(-15,-15), c(15,15), DEoptim.control(list(trace=FALSE, NP=50, itermax=50, parallelType = 2)))
#Fecha os clusters
stopCluster(cl)
#Guarda os melhores resultados.
fim <- outDEoptim $ optim $ bestmem
fim
Alguns comentários são importantes: as linhas 8 e 10 são utilizadas para se passar bibliotecas e objetos do R que são utilizados no cômputo da função que deve ser otimizada. Nesse caso, como não usamos nenhum pacote especial para o cômputo da função e nem bibliotecas esses comandos estão comentados. Caso deseje-se passar esses valores, basta atribuí-los na forma de lista em cada comando. Na função DEoptim o primeiro argumento é a função a ser minimizada, seguido pelos limites inferiores e superiores para os argumentos. O último argumento é uma lista que controla as condições da função de otimização: NP é o número de populações a serem geradas no algoritmo de Otimização Evolucionária, itermax é o número total de iterações e parallelType = 2 define a forma de paralelismo a ser considerada. Observe ainda que se o valor de NP e/ou itermax e o paralelismo não for adotado, esse processo pode ser muito lento computacionalmente, daí a vantagem de se utilizar o processamento em paralelo que pode reduzir esse tempo computacional significativamente. Mote ainda que o comando trace=FALSE é para suprimir os resultados em cada iteração, e caso deseje-se maximizar a função ao invés de minimizar, basta trabalhar com o valor do negativo da função, ou ainda com seu recíproco.

Nenhum comentário:

Postar um comentário