【问题标题】:Abort function after X seconds - lispX 秒后中止函数 - lisp
【发布时间】:2015-11-30 16:43:38
【问题描述】:

我一直在寻找一种在 lisp 上 X 秒后停止函数的方法,但我没有找到任何东西,也不知道该怎么做。

它用于在俄罗斯方块游戏的函数上寻找启发式权重,如果权重不好,程序将运行超过 30 秒,我不希望这样。请问大家有什么想法吗?

【问题讨论】:

  • 对此有答案,但它们不能移植; Common Lisp 标准不包括多处理/线程/等概念。你用clisp标记了这个问题;你在使用 CLISP 实现吗?还是其他一些实现?也就是说,bordeaux-threads 在某些实现线程 API 上提供了一个兼容层。一旦你有一些多线程工作,你可能会发现Common Lisp Timer 的答案很有用。
  • 虽然这些链接很有用,但我真的喜欢Vatine's answer
  • 如果我的猜测是正确的,那么这个问题的背景是一个人工智能 (AI) 项目,其中有一个锦标赛来积极增加最佳项目的等级。为每次比赛期间调用的函数提供了一个超时(查找最佳移动、解决方案等),超时后将取消该项目的比赛资格。

标签: lisp common-lisp clisp


【解决方案1】:

Common Lisp 有一个库:Trivial Timeout

API 很简单:Trivial Timeout API

【讨论】:

    【解决方案2】:

    一种可能的方法是传递一个“到期计时器”并检查当前时间是否晚于每次迭代的到期时间,如果已到期,则返回迄今为止的最佳解决方案。标准函数get-universal-time 可能很有用,但会为您提供秒的最小粒度。下面是一个粗略的骨架。如果您使用递归函数,只需将到期计时器与您传递的任何其他内容一起向下传递,并将其用作您的第一个递归终止标准。

    (defun do-tetris-stuff (tetris-weights expiry-time)
      (let ((best-solution nil))
        (loop while (and (<= expiry-time (get-universal-time))
                         (not (good-enough-p best-solution)))
              do (let ((next-solution ...))
                   (when (better-than-p next-solution best-solution)
                     (setf best-solution next-solution))))
        best-solution))
    

    【讨论】:

    • 我真的很喜欢这个答案。它表明这可以在没有任何多线程、计时器等的情况下完成,只要有某种方法可以定期检查时间。 +1(如果可以的话,还有更多)。
    • 除了指定一个让调用者负责的到期时间,你还可以做(defun do-stuff (weights &amp;optional (timeout 30) &amp;aux (expiry-time (+ (get-universal-time) timeout))) ...),它让调用者指定一个以秒为单位的超时,并将到期时间计算为该秒数加上当前世界时。
    • @JoshuaTaylor 存在一些问题,但这是可移植的,而且您经常会遇到诸如“搜索深度”之类的东西,无论如何都会限制解决方案空间的遍历。但是,如果您需要比“一秒”更精细的粒度,那么您就不走运了(或者在依赖于系统的代码中)。
    • 我认为使用get-internal-real-time 的时间粒度可能比get-universal-time 更精细。
    • @Renzo 但是你仍然需要弄清楚你的实现中内部时间的节奏。我承认,这并不完全是一个难题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    • 2012-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多