如何使用 GA 包在 R 中优化具有两个变量和多个参数的函数
How to optimize a function with two variables and several parameters in R with a GA package
我是遗传算法的初学者,尤其是GA算法。
我想知道如何优化具有两个自变量和多个参数的函数。
我的第一个变量是连续变量,第二个变量是二元变量。
这是我生成的代码,但它不起作用。
This is what i want to obtain
Var1_obs <- c(-1.942000, -1.338000, -2.065000, -2.080125, -3.247944, -5.365086,
-1.608000, -3.970000, -1.423000, -8.180000, -4.620000, -1.657000,
-5.200000, -6.850000, -6.950000, -1.180000, -1.175000, -1.969000,
-1.115000, -2.620000, -1.870000, -0.433000, -1.102000, -2.093687,
-2.480000, -0.580000, -0.600000, -1.807383, -2.367000, -2.276017,
-2.125331)
Var2_obs <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1)
TE_obs <- c(92.73958, 93.39356, 84.39019, 93.40717, 97.53228, 92.04734, 82.06016,
78.50015, 83.43671, 55.24498, 67.92513, 77.53455, 65.33344, 47.05005,
46.52794, 96.79697, 84.79326, 83.64457, 82.17259, 88.96605, 84.93663,
83.16691, 95.22838, 96.46441, 79.61302, 80.39901, 88.38439, 72.23954,
85.64084, 69.33542, 82.30360)
data<-data.frame(Var1_obs,Var2_obs,TE_obs)
plot(data$Var1_obs[data$Var2_obs==0],data$TE_obs[data$Var2_obs==0],
xlim=range(data$Var1_obs), ylim=range(data$TE_obs), col=2, pch=19,
xlab='Var1_obs', ylab='TE_obs')
points(data$Var1_obs[data$Var2_obs==1],data$TE_obs[data$Var2_obs==1],
xlim=range(data$Var1_obs), ylim=range(data$TE_obs), col=3, pch=19)
library(GA)
library(hydroGOF)
My_function <- function(Var1, Var2, P1, P2, P3, P4, P5, P6, P7) {
A <- (-1 * (Var1 + P1 - P2) - sqrt((Var1 + P1 - P2)^2 + 4 * (Var1 * P2))) / (2 * P2)
B <- 1 - P1 / Var1
C <- c(A, B)
Sel <- c(A > B, B > A)
RS <- C[Sel]
PC <- 100 / (1 + exp(P3 / 25 * (Var1 - P4)))
RMC <- (1 - RS)
symp <- RMC * (1 / (P5 / 1000) - 1) * 100 * (1 - P6)
apo <- (1 - PC / 100) * (1 / (P5 / 1000) - 1) * 100 * (P6)
TE_Pred <- (apo + symp) * (1 + P7 * Var2)
NRMSE <- (nrmse(TE_Pred, TE_obs, na.rm = T, norm = "sd"))
# if(is.na(NRMSE)|is.nan(NRMSE)|is.infinite(NRMSE)) NRMSE <- -1e6
return(NRMSE)
}
# ----------------------- BOUNDARIES --------------------------- #
P1 <- c(-3.5, -2.3)
P2 <- c(5, 15)
P3 <- c(15, 60)
P4 <- c(-7.5, -6)
P5 <- c(500, 600)
P6 <- c(0.3, 0.6)
P7 <- c(-1, 0)
min_boundary <- c(P1[1], P2[1], P3[1], P4[1], P5[1], P6[1], P7[1])
max_boundary <- c(P1[2], P2[2], P3[2], P4[2], P5[2], P6[2], P7[2])
ga(
type = "real-valued",
fitness = function(x) -My_function(Var1 = Var1_obs, Var2 = Var2_obs, P1[1],
P2[2], P3[3], P4[4], P5[5], P6[6], P7[7]),
lower = min_boundary, upper = max_boundary,
popSize = 50, maxiter = 1000, run = 100
)
我在 运行 代码
时得到了这个
#> GA | iter = 1 | Mean = NaN | Best = -Inf
#> GA | iter = 2 | Mean = NaN | Best = -Inf
#> Error in if (object@run >= run) break :
#> missing value where TRUE/FALSE needed
感谢您的帮助
ga
函数的设计方式,它需要一个接受一个输入(可以说是变量)的适应度函数。
一般解决方案
如果你想用两个变量 x1
和 x2
来最小化函数 f
(也就是说,你想找到 x1
和 x2
导致最小值 f(x1, x2)
),你必须像这样调用函数
# Taken from `?ga` 3) two-dimensional Rastrigin function
# slightly adopted to have three parameters (that are not optimized)
library(GA)
f <- function(x1, x2, p1 = 20, p2 = -10, p3 = 2) {
p1 + x1^2 + x2^2 + p2*(cos(p3*pi*x1) + cos(p3*pi*x2))
}
# evaluate the function at (2, 4)
f(2, 4, p1 = 20, p2 = -10, p3 = 2)
#> [1] 20
# minimize the Rastrigin function
GA <- ga(type = "real-valued", fitness = function(x) -f(x[1], x[2], 20, 10, 2),
lower = c(-5.12, -5.12), upper = c(5.12, 5.12),
popSize = 50, maxiter = 100, seed = 1521)
summary(GA)
#> -- Genetic Algorithm -------------------
#>
#> GA settings:
#> Type = real-valued
#> Population size = 50
#> Number of generations = 100
#> Elitism = 2
#> Crossover probability = 0.8
#> Mutation probability = 0.1
#> Search domain =
#> x1 x2
#> lower -5.12 -5.12
#> upper 5.12 5.12
#>
#> GA results:
#> Iterations = 100
#> Fitness function value = -0.4974871
#> Solution =
#> x1 x2
#> [1,] -0.4976645 0.4975342
适合您问题的解决方案
如果您想找到最小化 My_Function()
函数的值 P1
- P7
(给定 Val1
和 Val2
的值,你可以这样做:
# ...
res <- ga(
type = "real-valued",
fitness = function(x) -My_function(Var1 = Var1_obs, Var2 = Var2_obs,
x[1], x[2], x[3], x[4], x[5], x[6], x[7]),
lower = min_boundary, upper = max_boundary,
popSize = 50, maxiter = 1000, run = 100
)
summary(res)
#> -- Genetic Algorithm -------------------
#>
#> GA settings:
#> Type = real-valued
#> Population size = 50
#> Number of generations = 1000
#> Elitism = 2
#> Crossover probability = 0.8
#> Mutation probability = 0.1
#> Search domain =
#> x1 x2 x3 x4 x5 x6 x7
#> lower -3.5 5 15 -7.5 500 0.3 -1
#> upper -2.3 15 60 -6.0 600 0.6 0
#>
#> GA results:
#> Iterations = 341
#> Fitness function value = -63.2
#> Solution =
#> x1 x2 x3 x4 x5 x6 x7
#> [1,] -3.353621 9.373742 27.51849 -6.217355 511.5233 0.5698783 -0.0307688
请注意我们如何将 x
中的值替换为您问题中的参数 P1
- P7
。
为什么 -my_function()
?
查阅?ga
,我们看到ga-function maximizes目标函数,正如你想最小化函数,取负有效地最小化函数。
我是遗传算法的初学者,尤其是GA算法。 我想知道如何优化具有两个自变量和多个参数的函数。 我的第一个变量是连续变量,第二个变量是二元变量。 这是我生成的代码,但它不起作用。
This is what i want to obtain
Var1_obs <- c(-1.942000, -1.338000, -2.065000, -2.080125, -3.247944, -5.365086,
-1.608000, -3.970000, -1.423000, -8.180000, -4.620000, -1.657000,
-5.200000, -6.850000, -6.950000, -1.180000, -1.175000, -1.969000,
-1.115000, -2.620000, -1.870000, -0.433000, -1.102000, -2.093687,
-2.480000, -0.580000, -0.600000, -1.807383, -2.367000, -2.276017,
-2.125331)
Var2_obs <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1)
TE_obs <- c(92.73958, 93.39356, 84.39019, 93.40717, 97.53228, 92.04734, 82.06016,
78.50015, 83.43671, 55.24498, 67.92513, 77.53455, 65.33344, 47.05005,
46.52794, 96.79697, 84.79326, 83.64457, 82.17259, 88.96605, 84.93663,
83.16691, 95.22838, 96.46441, 79.61302, 80.39901, 88.38439, 72.23954,
85.64084, 69.33542, 82.30360)
data<-data.frame(Var1_obs,Var2_obs,TE_obs)
plot(data$Var1_obs[data$Var2_obs==0],data$TE_obs[data$Var2_obs==0],
xlim=range(data$Var1_obs), ylim=range(data$TE_obs), col=2, pch=19,
xlab='Var1_obs', ylab='TE_obs')
points(data$Var1_obs[data$Var2_obs==1],data$TE_obs[data$Var2_obs==1],
xlim=range(data$Var1_obs), ylim=range(data$TE_obs), col=3, pch=19)
library(GA)
library(hydroGOF)
My_function <- function(Var1, Var2, P1, P2, P3, P4, P5, P6, P7) {
A <- (-1 * (Var1 + P1 - P2) - sqrt((Var1 + P1 - P2)^2 + 4 * (Var1 * P2))) / (2 * P2)
B <- 1 - P1 / Var1
C <- c(A, B)
Sel <- c(A > B, B > A)
RS <- C[Sel]
PC <- 100 / (1 + exp(P3 / 25 * (Var1 - P4)))
RMC <- (1 - RS)
symp <- RMC * (1 / (P5 / 1000) - 1) * 100 * (1 - P6)
apo <- (1 - PC / 100) * (1 / (P5 / 1000) - 1) * 100 * (P6)
TE_Pred <- (apo + symp) * (1 + P7 * Var2)
NRMSE <- (nrmse(TE_Pred, TE_obs, na.rm = T, norm = "sd"))
# if(is.na(NRMSE)|is.nan(NRMSE)|is.infinite(NRMSE)) NRMSE <- -1e6
return(NRMSE)
}
# ----------------------- BOUNDARIES --------------------------- #
P1 <- c(-3.5, -2.3)
P2 <- c(5, 15)
P3 <- c(15, 60)
P4 <- c(-7.5, -6)
P5 <- c(500, 600)
P6 <- c(0.3, 0.6)
P7 <- c(-1, 0)
min_boundary <- c(P1[1], P2[1], P3[1], P4[1], P5[1], P6[1], P7[1])
max_boundary <- c(P1[2], P2[2], P3[2], P4[2], P5[2], P6[2], P7[2])
ga(
type = "real-valued",
fitness = function(x) -My_function(Var1 = Var1_obs, Var2 = Var2_obs, P1[1],
P2[2], P3[3], P4[4], P5[5], P6[6], P7[7]),
lower = min_boundary, upper = max_boundary,
popSize = 50, maxiter = 1000, run = 100
)
我在 运行 代码
时得到了这个#> GA | iter = 1 | Mean = NaN | Best = -Inf
#> GA | iter = 2 | Mean = NaN | Best = -Inf
#> Error in if (object@run >= run) break :
#> missing value where TRUE/FALSE needed
感谢您的帮助
ga
函数的设计方式,它需要一个接受一个输入(可以说是变量)的适应度函数。
一般解决方案
如果你想用两个变量 x1
和 x2
来最小化函数 f
(也就是说,你想找到 x1
和 x2
导致最小值 f(x1, x2)
),你必须像这样调用函数
# Taken from `?ga` 3) two-dimensional Rastrigin function
# slightly adopted to have three parameters (that are not optimized)
library(GA)
f <- function(x1, x2, p1 = 20, p2 = -10, p3 = 2) {
p1 + x1^2 + x2^2 + p2*(cos(p3*pi*x1) + cos(p3*pi*x2))
}
# evaluate the function at (2, 4)
f(2, 4, p1 = 20, p2 = -10, p3 = 2)
#> [1] 20
# minimize the Rastrigin function
GA <- ga(type = "real-valued", fitness = function(x) -f(x[1], x[2], 20, 10, 2),
lower = c(-5.12, -5.12), upper = c(5.12, 5.12),
popSize = 50, maxiter = 100, seed = 1521)
summary(GA)
#> -- Genetic Algorithm -------------------
#>
#> GA settings:
#> Type = real-valued
#> Population size = 50
#> Number of generations = 100
#> Elitism = 2
#> Crossover probability = 0.8
#> Mutation probability = 0.1
#> Search domain =
#> x1 x2
#> lower -5.12 -5.12
#> upper 5.12 5.12
#>
#> GA results:
#> Iterations = 100
#> Fitness function value = -0.4974871
#> Solution =
#> x1 x2
#> [1,] -0.4976645 0.4975342
适合您问题的解决方案
如果您想找到最小化 My_Function()
函数的值 P1
- P7
(给定 Val1
和 Val2
的值,你可以这样做:
# ...
res <- ga(
type = "real-valued",
fitness = function(x) -My_function(Var1 = Var1_obs, Var2 = Var2_obs,
x[1], x[2], x[3], x[4], x[5], x[6], x[7]),
lower = min_boundary, upper = max_boundary,
popSize = 50, maxiter = 1000, run = 100
)
summary(res)
#> -- Genetic Algorithm -------------------
#>
#> GA settings:
#> Type = real-valued
#> Population size = 50
#> Number of generations = 1000
#> Elitism = 2
#> Crossover probability = 0.8
#> Mutation probability = 0.1
#> Search domain =
#> x1 x2 x3 x4 x5 x6 x7
#> lower -3.5 5 15 -7.5 500 0.3 -1
#> upper -2.3 15 60 -6.0 600 0.6 0
#>
#> GA results:
#> Iterations = 341
#> Fitness function value = -63.2
#> Solution =
#> x1 x2 x3 x4 x5 x6 x7
#> [1,] -3.353621 9.373742 27.51849 -6.217355 511.5233 0.5698783 -0.0307688
请注意我们如何将 x
中的值替换为您问题中的参数 P1
- P7
。
为什么 -my_function()
?
查阅?ga
,我们看到ga-function maximizes目标函数,正如你想最小化函数,取负有效地最小化函数。