我有一棵树,
A
/ \
B C
/\ \
D E F
表示为列表,
(A (B (D) (E)) (C (F)))
它实际上是一棵非常大的树,所以我想做的就是开始搜索,如果我找不到我要找的东西说100毫秒保存状态,返回,做一些家务,然后再打电话搜索并继续我离开的地方。基本上我正在使用的模拟给了我一定的时间来完成搜索。我正在寻找关于如何实现这一目标的想法/技巧? (在Clojure,Java)
答案 0 :(得分:7)
线程可能是最简单的解决方案,但在单个线程上自己管理它并不是很困难。 基本思想是创建一个闭包,表示完成任务需要完成的工作,如果没有时间完成,则返回结果而不是结果。这是一个草图:它增加了一系列数字,并且每十次操作而不是每100ms被中断。 编辑:因为Clojure没有尾调用优化,所以创建一个thunk然后调用它会占用堆栈。如果您可能在需要中断之前执行超过几千步,则会出现堆栈溢出。唯一可行的解决方案是在 如果必须编写多个这样的“可挂起”函数,你可以用宏来抽象出来。(let [timer (atom 9)]
(defn keep-going? []
(not= 0 (swap! timer #(mod (inc %) 10)))))
(defn saving-addition [sum xs]
(if-let [[x & more] (seq xs)]
(let [next-thunk (fn [] (saving-addition (+ x sum) more))]
(if (keep-going?)
(next-thunk)
next-thunk))
sum))
(defn monitor [xs]
(loop [thunk (saving-addition 0 xs)]
(if (fn? thunk)
(do
(println "Saving execution state")
(recur (thunk)))
thunk)))
user> (monitor (range 25))
Saving execution state
Saving execution state
Saving execution state
300
recur
和延续中复制thunk的主体,例如(defn saving-addition [sum xs]
(if-let [[x & more] (seq xs)]
(let [sum (+ x sum)]
(if (keep-going?)
(recur sum more)
#(saving-addition sum more)))
sum))
答案 1 :(得分:2)
如果您不介意线程的开销,请将搜索放在一个稍微有点工作的线程上,然后不时产生。
线程的优点是您不必以编程方式保存状态;系统会为你做。
你必须为此付出复杂的代价,因为搜索的结果会异步进入,你必须安排以某种方式得到它。此外,您可能需要设置100毫秒的计时器。很多代码。 :)
答案 2 :(得分:0)
最好的办法是在你可以轻松保存状态并稍后恢复的位置(你可以尝试使函数递归以便轻松找到最佳点)。
然后在那些点上,您可以选择保存状态或继续