在R中实现元启发式算法

时间:2012-01-28 08:48:21

标签: algorithm r

我在哪里可以找到一些包含免费数据示例的优秀教程,关于如何在R中实现元启发式算法?

我问这个是因为我找到了很多关于如何做的资源,但是我在从理论转向实施它时遇到了很大的问题。

Book Essentials of Metaheuristics (by Professor Sean Luke)是一本很好的书,但对于那些编程背景有限且没有算法经验的人来说,如果没有一些带有数据的“真实例子”,很难实现它们

从Metaheuristics的Book Essentials(页16)中选取一个例子:

Algorithm 5 Steepest Ascent Hill-Climbing
1: n ← number of tweaks desired to sample the gradient
2: S ← some initial candidate solution
3: repeat
4: R ← Tweak(Copy(S))
5: for n − 1 times do
6: W ← Tweak(Copy(S))
7: if Quality(W) > Quality(R) then
8: R ← W
9: if Quality(R) > Quality(S) then
10: S ← R
11: until S is the ideal solution or we have run out of time
12: return S

我想在给我一个使用真实数据的例子之后会有一些东西。 我正在寻找like this

我见过很多关于特定算法的问题(比如GA),也许我复制了已经存在的问题,但我没有特别发现这个问题,但如果重复这个问题,请警告我。

其他语言如python也会有所帮助(例如任何与R类似的语言)。

1 个答案:

答案 0 :(得分:5)

我不熟悉metaheuristics作为一个字段,但是你给它的伪代码实际上很容易翻译成R语法:

# I never metaheuristic I didn't like
metah <- function(S, quality, tweak, n, outer.limit, threshold)
{
    outer.n <- 0
    repeat {
        outer.n <- outer.n + 1
        R <- tweak(S)
        for(i in seq_len(n - 1))
        {
            W <- tweak(S)
            if(quality(W) > quality(R))
                R <- W
        }
        if(quality(R) > quality(S))
            S <- R
        if(quality(S) >= threshold || outer.n >= outer.limit)
            break
    }
    S
}

现在,您只需为qualitytweak提供合适的功能。

例如,假设我们想要拟合线性回归。在这种情况下,我们有一个响应向量y,以及一个向量矩阵X。解S解是每一步的候选系数的向量,“质量”是平方误差损失:sum((y - yhat)^2)。请注意,在这里,降低的质量越好。

对于tweak,我们可以使用当前解S的正态分布,并使用用户指定的协方差矩阵。

然后可以将其编码为

require(MASS) # for mvrnorm

quality <- function(S, y, X)
sum((y - X %*% S)^2)

tweak <- function(S, sigma=rep(1, length(s))
S + mvrnorm(length(S), 0, sigma)

metah <- function(y, X, quality, tweak, n, outer.limit, threshold)
{
    outer.n <- 0
    S <- rep(1, ncol(X))
    repeat {
        outer.n <- outer.n + 1
        R <- tweak(S)
        for(i in seq_len(n - 1))
        {
            W <- tweak(S)
            if(quality(W, y, X) < quality(R, y, X)) # note reversed comparison!
                R <- W
        }
        if(quality(R, y, X) < quality(S, y, X))
            S <- R
        if(quality(S) <= threshold || outer.n >= outer.limit)
            break
    }
    S
}

进一步的改进可能是:

  1. 使用for(i in ...)

  2. 将内循环*apply替换为矢量化代码
  3. 让调整的分布取决于解决方案的特征,而不是如上所述对其进行硬编码(特别是,sigma应根据X变量的比例而变化)

  4. 根据您的最低进度表达threshold,例如每个候选解决方案从上一次迭代中移动了多远。