2011-10-04 45 views
14

我正在Clojure中构建一个系统,实时消耗事件并根据最近收到多少类似消息对其执行操作。我想使用基于牛顿冷却的近因分数来实现这一点。使用牛顿冷却clojure中的新近性映射

换句话说,当一个事件到达时,我希望能够给它一个1.0之间的分数(以前从未发生过,或者牛顿方程中的“环境温度”)和10.0(热的热的热量,发生过几次在过去的一分钟)。

我对这个数据结构是什么样子有个模糊的想法 - 每个“事件类型”都是一个映射关键字,每个映射值都应该包含一些前一个事件的时间戳集,也许是当前“热“的事件类型,但我不能完全弄清楚如何开始实施超越。具体来说,我很难弄清楚如何从牛顿的非常通用的实际方程中去,并将其应用于这个特定的场景。

有没有人有任何指针?有人可能会建议一个更简单的“新近程度分数算法”来让我开始,这可以用牛顿冷却道路取代吗?

编辑:这是一些clojure代码!它将这些事件称为字母,但显然可以重新用于采取任何其他类型的对象。

(ns heater.core 
    (:require [clojure.contrib.generic.math-functions :as math])) 

(def letter-recency-map (ref {})) 

(def MIN-TEMP 1.0) 
(def MAX-TEMP 10.0) 
;; Cooling time is 15 seconds 
(def COOLING-TIME 15000) 
;; Events required to reach max heat 
(def EVENTS-TO-HEAT 5.0) 

(defn temp-since [t since now] 
    (+ 
     MIN-TEMP 
     (* 
      (math/exp (/ 
       (- (- now since)) 
       COOLING-TIME)) 
      (- t MIN-TEMP)))) 

(defn temp-post-event [temp-pre-event] 
    (+ temp-pre-event 
     (/ 
      (- MAX-TEMP temp-pre-event) 
      EVENTS-TO-HEAT))) 

(defn get-letter-heat [letter] 
     (dosync 
      (let [heat-record (get (ensure letter-recency-map) letter)] 
      (if (= heat-record nil) 
       (do 
       (alter letter-recency-map conj {letter {:time (System/currentTimeMillis) :heat 1.0}}) 
       MIN-TEMP) 
       (let [now (System/currentTimeMillis) 
        new-temp-cooled (temp-since (:heat heat-record) (:time heat-record) now) 
        new-temp-event (temp-post-event new-temp-cooled)] 
        (alter letter-recency-map conj {letter {:time now :heat new-temp-event}}) 
        new-temp-event))))) 
+0

+1是一个很好的问题。我会很乐意看到你得到的答案。 –

+0

+1。并添加了'算法'标签。 – 4e6

回答

5

没有任何事件,冷却方程的解是指数衰减。说T_0处于冷却期开始时的温度,dt是时间步长(从系统时间或任何计算的),因为你评估的温度为T_0

T_no_events(dt) = T_min + (T_0 - T_min)*exp(- dt/t_cooling) 

因为你的事件是离散的冲动,你的最高温度,你希望每个事件以一定的比率:

T_post_event = T_pre_event + (T_max - T_pre_event)/num_events_to_heat 

一些注意事项:

  • t_cooling是事情冷却的时间因素为1/e = 1/(2.718...)

  • num_events_to_heat是具有与T_max相当的效果所需的事件数量。它可能应该是一个中等大的正值(说5.0或更多?)。请注意,如果num_events_to_heat==1.0,每个事件都会将温度重置为T_max,这不是很有趣,所以该值至少应大于1。从理论上讲,加热和冷却不应该分别达到最高和最低温度(假设参数如上设定,并且你在两者之间的某处开始)。但在实践中,过程的指数特性应该足够接近,因为没有区别...

  • 要实现此目的,只需要存储上次更新的时间戳和温度。当您收到活动时,请执行制冷步骤,然后进行制热事件,并使用新的温度和时间戳进行更新。

  • 请注意,只读查询不需要更新:您可以计算自上次更新以来的冷却。

+0

t_cooling是一个“时间常数” - 时间冷却到原始三角洲的36.8%。这是一个很好的答案。它显示了冷却点质量的物理学的一个很好的把握,并以一种新颖的方式应用它。 – duffymo