【问题标题】:Get out of infinite while loop退出无限的while循环
【发布时间】:2017-01-20 12:06:28
【问题描述】:

while 循环卡在 R 中的无限循环中时,识别它的最佳方法是什么?

这是我的情况:

diff_val = Inf
last_val = 0

while(diff_val > 0.1){

    ### calculate val from data subset that is greater than the previous iteration's val
    val = foo(subset(data, col1 > last_val))

    diff_val = abs(val - last_val) ### how much did this change val?
    last_val = val ### set last_val for the next iteration
}

目标是让val越来越接近稳定值,当val在上一次迭代中val的0.1以内时,则认为它足够稳定并从while 循环。我的问题是,对于某些数据集,val 在两个值之间来回交替卡住。例如,在 27.0 和 27.7 之间来回迭代。因此,它永远不会稳定下来。如果发生这种情况,我该如何打破while 循环?

我知道break,但不知道如何告诉循环何时使用它。我想保持之前两次迭代的值会起作用,但我不知道如何保持两次迭代前的值......

while(diff_val > 0.1){

    val = foo(subset(data, col1 > last_val))

    diff_val = abs(val - last_val)
    last_val = val

    if(val == val_2_iterations_ago) break
}

如何创建val_2_iterations_ago

对不可重现的代码表示歉意。复制这种情况所需的真正的foo()data 不是我要分享的……不过,它们并不是解决控制流问题的关键。

【问题讨论】:

  • 该过程通常是递减的吗?当超过某个(任意)限制时,您可能能够跟踪它不减少和中断的次数。

标签: r loops while-loop


【解决方案1】:

我不知道只跟踪前两次迭代是否真的就足够了,但为此添加逻辑并不太麻烦。

逻辑是每次迭代,倒数第二个值成为最后一个值,最后一个值成为当前值,当前值从foo()派生而来。考虑这段代码:

while (diff_val > 0.1) {
    val <- foo(subset(data, col1 > last_val))

    if (val == val_2_iterations_ago) break

    diff_val = abs(val - last_val)
    val_2_iterations_ago <- last_val
    last_val <- val
}

【讨论】:

  • 我同意,三个或更多交替值的循环是可能的。如果可以概括这一点,那就太好了!
【解决方案2】:

另一种可能更通用的方法是跟踪您的迭代并设置最大值。

将此与蒂姆的好答案配对:

iter = 0
max_iter = 1e6
while (diff_val > 0.1 & iter < max_iter) {
    val <- foo(subset(data, col1 > last_val))

    if (val == val_2_iterations_ago) break

    diff_val = abs(val - last_val)
    val_2_iterations_ago <- last_val
    last_val <- val
    iter = iter + 1
}

【讨论】:

    【解决方案3】:

    这通常是如何完成的,你有:

    • 收敛容差,因此当您的目标函数没有明显变化时,算法被视为已收敛
    • 对迭代次数的限制,以保证代码最终终止
    • 检查目标函数实际上正在减少,以捕捉它发散/循环的情况(许多优化算法的设计是不应该发生这种情况,但在你的情况下它确实发生了)

    伪代码:

    oldVal <- Inf
    for(i in 1:NITERS)
    {
        val <- objective(x)
        diffVal <- val - oldVal
        converged <- (diffVal <= 0 && abs(diffVal) < TOL)
        if(converged || diffVal > 0)
            break
        oldVal <- val
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-18
      • 1970-01-01
      • 2016-11-07
      相关资源
      最近更新 更多