我正在使用 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/417263.html
標籤:
