我有一个用于模拟退火算法的脚本,并且想要将搜索限制为超级立方体。
simulated_annealing <- function(func, s0, niter = 1, epsilon = 0.01) {
# ##s=state, f=funcion, b=best, c=current, n=neighbour
s_b <- s_c <- s_n <- s0
f_b <- f_c <- f_n <- func(s_n)
for (k in 1:niter) {
Temperatura <- (1 - epsilon)^k
s_n <- rnorm(2, s_c, 1)
f_n <- func(s_n)
if (f_n < f_c || runif(1, 0, 1) < exp(-(f_n - f_c) / Temperatura)) {
s_c <- s_n
f_c <- f_n
}
if (f_n < f_b) {
s_b <- s_n
f_b <- f_n
}
return(list(iteraciones = niter, Mejor_valor = f_b, Mejor_estado = s_b))
}}
您可以这样使用它:
sol <- simulated_annealing(rastr, niter = 100, epsilon = 0.91, s0 = c(0, 2))
我想在搜索空间中添加限制,以便它仅在超立方体x_i = [-5.12,5.12]中移动,但我不知道如何开始。我尝试使用while,但是它停止了该功能。
请和谢谢
答案 0 :(得分:0)
我设法找到了一个解决方案,尽管有点不爽。完成的脚本如下:
simulated_annealing <- function(func, s0, niter = 1000, epsilon = 0.1) {
x_upper = 5.12
x_lower = -5.12
# Inicializamos
## s simboliza estado
## f simboliza valor de la funcion
## b simboliza el mejor obtenido hasta ahora
## c simboliza el presente
## n simboliza vecino
s_b <- s_c <- s_n <- s0
f_b <- f_c <- f_n <- func(s_n)
message("Iteracion\tMejor\tActual\tVecino\tTemperatura")
message(sprintf("%i\t%.4f\t%.4f\t%.4f\t%.4f", 0L, f_b, f_c, f_n, 1000))
for (k in 1:niter) {
Temperatura <- (1 - epsilon)^k #Exponencial
# Contemplamos un vecino aleatorio
s_n <- rnorm(2, s_c, 1)
f_n <- func(s_n)
while (f_n > x_upper | f_n < x_lower) {
s_c <- s_c[! s_c %in% c(s_n)] ##THIS IS THE ADDED LINE
s_n <- rnorm(2, s_c, 1)
f_n <- func(s_n)
}
# # Actualizamos el estado actual
if (f_n < f_c || runif(1, 0, 1) < exp(-(f_n - f_c) / Temperatura)) {
s_c <- s_n
f_c <- f_n
}
# # Actualizamos el estado al mejor conseguido
if (f_n < f_b) {
s_b <- s_n
f_b <- f_n
}
if (k %% 1000==0) {
message(sprintf("%i\t%.4f\t%.4f\t%.4f\t%.4f", k, f_b, f_c, f_n, Temperatura))}
}
return(list(iteraciones = niter, Mejor_valor = f_b, Mejor_estado = s_b))
}