На этой неделе на конференции Rmetrics прошла интересная дискуссия об эвристической оптимизации. Начальная точка была проста: в сложных задачах оптимизации (здесь мы имеем в виду множество локальных максимумов, например), нам не обязательно нужны чрезвычайно продвинутые алгоритмы, которые очень быстро сходятся, если мы не можем гарантировать, что они достигают оптимума. Очень быстрая сходимость с большой числовой точностью до некоторой точки (это не та точка, которую мы ищем) бесполезна. И некоторые алгоритмы могут быть намного медленнее, но, по крайней мере, они с большей вероятностью сходятся к оптимальному. С чего бы мы ни начали.
Мы испытали это с Матье, в то время как мы искали максимальную вероятность нашего MINARпроцесс: генетический алгоритм выполнил чрезвычайно хорошо. Идея предельно проста и естественна. Давайте рассмотрим в качестве отправной точки следующий алгоритм,
- Начните с некоторых
- На шаге нарисуйте точку в окрестности ,
- либо тогда
- или тогда
Это просто (если вы не введете подробности о том, каким должен быть такой район). Но используя такой алгоритм, вы можете попасть в ловушку и привлечь к себе некоторые локальные оптимумы, если
окрестности недостаточно велики. Альтернативой этому методу является следующее: может быть интересно изменить немного больше, и вместо того, чтобы измениться, когда у нас есть максимум, мы меняемся, если у нас есть почти максимум. А именно на шаге
,
- либо тогда
- или тогда
для некоторых . Чтобы проиллюстрировать идею, рассмотрим следующую функцию
> f=function(x,y) { r <- sqrt(x^2+y^2); + 1.1^(x+y)*10 * sin(r)/r }
(на некоторой ограниченной поддержке). Здесь, выбирая шум и
значения произвольно, мы получили следующие сценарии
> x0=15 > MX=matrix(NA,501,2) > MX[1,]=runif(2,-x0,x0) > k=.5 > for(s in 2:501){ + bruit=rnorm(2) + X=MX[s-1,]+bruit*3 + if(X[1]>x0){X[1]=x0} + if(X[1]<(-x0)){X[1]=-x0} + if(X[2]>x0){X[2]=x0} + if(X[2]<(-x0)){X[2]=-x0} + if(f(X[1],X[2])+k>f(MX[s-1,1], + MX[s-1,2])){MX[s,]=X} + if(f(X[1],X[2])+k<=f(MX[s-1,1], + MX[s-1,2])){MX[s,]=MX[s-1,]} +}
Это не всегда сходится к оптимальному,
а иногда мы просто пропустили это из-за крайне неудачного
Обратите внимание, что если мы запустим 10 000 сценариев (с разными случайными шумами и начальной точкой), в 50% сценариев мы достигнем максимума. Или, по крайней мере, мы рядом с ним, сверху.
Что, если мы сравним со стандартной процедурой оптимизации, такой как Nelder-Mead, или квази градиент? Поскольку мы ищем максимумы в ограниченной области, мы можем использовать следующую функцию:
> g=function(x) f(x[1],x[2]) > optim(X0, g,method="L-BFGS-B", + lower=-c(x0,x0),upper=c(x0,x0))$par
В этом случае, если мы запустим алгоритм с 10 000 случайных начальных точек, это то, где мы заканчиваем, внизу справа (в то время как эвристический метод находится слева),
Только в 15% сценариев мы смогли достичь региона, где максимум.
Так что здесь, похоже, эвристический метод работает очень хорошо, если не нужно достигать максимума с большой точностью. Что обычно бывает на самом деле.