2011-10-04 3 views
14

私は、リアルタイムでイベントを消費し、最近受信された類似のメッセージの数に応じて動作するClojureのシステムを構築しています。私はニュートンの冷却に基づいて最新のスコアを使用してこれを実装したいと思います。ニュートンの冷却を使用するclojureの最新のマップ

つまり、イベントが到着したときに、1.0(ニュートンの式の「周囲温度」または以前に起こったことはない)と10.0(ホットホットホット、数回発生した過去1分間に)。

すべての「イベントタイプ」はマップキーであり、すべてのマップ値には以前のイベントのタイムスタンプのセットが含まれている必要があります。現在の "そのイベントタイプでは「熱」がありますが、それを超えて実装を開始する方法はわかりません。具体的には、非常に一般的なニュートンの実際の方程式からどのように移動して、この特定のシナリオに適用するのかがわかりません。

誰でもポインタを持っていますか?誰かが簡単に「レニエントスコアアルゴリズム」を提案して、ニュートンの道を冷やすことで置き換えることができましたか?

EDIT:ここにいくつかのクロージャーコードがあります。それは文字としてのイベントを参照していますが、他の種類のオブジェクトを取るために明らかに再利用することができます。

(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。そして 'algorithm'タグを追加しました。 – 4e6

答えて

5

イベントがない場合、冷却方程式の解は指数関数的減衰である。

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

あなたのイベントは、離散インパルスなので、そして:T_0は冷却期間の開始時の温度で、dtはあなたがT_0する温度を評価したので、(システム時間または何から計算)タイムステップであると言いますあなたはイベントごとに所定の比率を望む、最高温度を持っている:

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

関連する問題