2011-10-04 27 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