我正在使用 R 编程语言。
我正在尝试 使用带替换的随机搜索和不带替换的随机搜索来优化Rastrign 函式:
Rastrigin <- function(x1, x2)
{
20 x1^2 x2^2 - 10*(cos(2*pi*x1) cos(2*pi*x2))
}
x1 <- x2 <- seq(-5.12, 5.12, by = 0.1)
f <- outer(x1, x2, Rastrigin)
第 1 部分:带替换的随机搜索:
为了进行替换采样,我生成了 100 个点(我将这些点转换为整数格式,以便更容易看出哪些点与Part 2重复),然后在这 100 个点处评估函式。然后我提取了对应于函式最小值的资料行。我还记录了花费的时间:
start.time <- Sys.time()
x1 = as.integer(rnorm(100,5,5))
x2 = as.integer(rnorm(100,5,5))
func_value = 20 x1^2 x2^2 - 10*(cos(2*pi*x1) cos(2*pi*x2))
frame = data.frame(x1,x2,func_value)
sort_frame <- frame[order(func_value),]
final_answer = sort_frame[1,]
end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken
Time difference of 0.01810408 secs
第 2 部分:无替换的随机搜索:
由于我不知道如何为传统方式撰写代码来执行不带替换的随机搜索(即生成随机值,看看这个生成的值是否已经发生:如果没有,则在这个值处评估函式,否则生成新值直到产生了看不见的值) - 因为我想以 100 个值评估函式,所以我决定生成 200 个值,希望这 200 个值中至少有 100 个值是唯一的。然后,我重复了上述程序:
start.time <- Sys.time()
x1 = as.integer(rnorm(200,5,5))
x2 = as.integer(rnorm(200,5,5))
frame = data.frame(x1,x2)
de_duplicated = frame[!(duplicated(frame) | duplicated(frame, fromLast = TRUE)), ]
#check to make sure at least 100 values in "de_duplicated"
ifelse(nrow(de_duplicated)<100, "BAD", "GOOD")
[1] "GOOD"
#only keep 100 values in de_duplicated:
de_duplicated = de_duplicated[1:100,]
func_value = 20 de_duplicated$x1^2 de_duplicated$x2^2 - 10*(cos(2*pi*de_duplicated$x1) cos(2*pi*de_duplicated$x2))
final_frame = data.frame(de_duplicated$x1,de_duplicated$x2,func_value)
sort_frame <- final_frame[order(func_value),]
final_answer = sort_frame[1,]
end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken
Time difference of 0.03689885 secs
我的问题:因为我有兴趣比较第 1 部分和第 2部分的时间- 我认为这不公平,因为我以非常“笨拙”的方式撰写了第 2 部分的代码。
如果您以更“传统”的方式撰写第 2 部分的代码,即使用“while 回圈”,这会减少第 2 部分所需的时间吗?有人请告诉我如何做到这一点 - 实际上是使用“while 回圈”撰写不带替换的随机搜索(即第 2 部分),实际上是传统的方法吗?
谢谢!
uj5u.com热心网友回复:
以下是我可以在整数值处对函式进行采样的示例方法,无论是否替换:
set.seed(123)
fSearchReplace <- function() {
# sampling with replacement
x1 <- as.integer(rnorm(100, 5, 5))
x2 <- as.integer(rnorm(100, 5, 5))
func_value <- 20 x1^2 x2^2 - 10*(cos(2*pi*x1) cos(2*pi*x2))
idxMin <- which.min(func_value)
frame <- data.frame(x1 = x1[idxMin], x2 = x2[idxMin], func_value = func_value[idxMin])
}
fSearchNoReplace1 <- function() {
# sampling without replacement by rejection
frame <- unique.data.frame(data.frame(x1 = as.integer(rnorm(200, 5, 5)), x2 = as.integer(rnorm(200, 5, 5))))
while (nrow(frame) < 100L) {
sz <- (100L - nrow(frame))*2L
frame <- unique.data.frame(rbind(frame, data.frame(x1 = as.integer(rnorm(sz,5,5)), x2 = as.integer(rnorm(sz, 5, 5)))))
}
func_value <- 20 frame[1:100,]$x1^2 frame[1:100,]$x2^2 - 10*(cos(2*pi*frame[1:100,]$x1) cos(2*pi*frame[1:100,]$x2))
idxMin <- which.min(func_value)
frame <- data.frame(x1 = frame$x1[idxMin], x2 = frame$x2[idxMin], func_value = func_value[idxMin])
}
fSearchNoReplace2 <- function() {
# sampling without replacement using weights
p <- diff(pnorm(-15.5:5.5, 5, 5))
w1 <- c(p, rev(head(p, -1)))
frame <- setNames(expand.grid(rep(list(-15:25), 2))[sample(1681, 100, prob = outer(w1, w1)),], c("x1", "x2"))
frame$func_value <- 20 frame$x1^2 frame$x2^2 - 10*(cos(2*pi*frame$x1) cos(2*pi*frame$x2))
frame <- frame[which.min(frame$func_value),]
}
print(fSearchReplace(), row.names = FALSE)
#> x1 x2 func_value
#> 0 0 0
print(fSearchNoReplace1(), row.names = FALSE)
#> x1 x2 func_value
#> 1 0 1
print(fSearchNoReplace2(), row.names = FALSE)
#> x1 x2 func_value
#> 0 0 0
microbenchmark::microbenchmark(fSearchReplace(), fSearchNoReplace1(), fSearchNoReplace2())
#> Unit: microseconds
#> expr min lq mean median uq max neval
#> fSearchReplace() 220.7 255.65 298.925 291.60 324.40 490.8 100
#> fSearchNoReplace1() 802.0 880.55 1043.916 1027.65 1132.70 2036.8 100
#> fSearchNoReplace2() 495.7 530.85 650.703 610.35 679.65 2779.4 100
注意:如果搜索不限于整数,rnorm
可以视为无放回抽样。从 100中得到两对相同的对的概率x1
实际上x2
是 0(这就是为什么rnorm
没有replace
自变量)。
uj5u.com热心网友回复:
如果没有替换,您不会使用 while 回圈进行采样。要么使用sample
,它有一个论点replace
。或者使用指定矢量的某种形式的随机排序:
x <- 1:10
## [1] 1 2 3 4 5 6 7 8 9 10
x[order(runif(length(x)))]
## [1] 6 8 2 5 3 7 1 10 9 4
0 评论