Карта давности в clojure с использованием ньютоновского охлаждения

Я создаю систему на Clojure, которая принимает события в реальном времени и действует на них в зависимости от того, сколько похожих сообщений было получено за последнее время. Я хотел бы реализовать это, используя оценку недавности, основанную на ньютоновском охлаждении.

Другими словами, когда наступает событие, я хочу иметь возможность присвоить ему оценку от 1,0 (никогда раньше не происходило, или «температура окружающей среды» в уравнении Ньютона) до 10,0 (горячо, горячо, горячо, происходило несколько раз в за последнюю минуту).

У меня есть смутное представление о том, как выглядит эта структура данных - каждый «тип события» является ключом карты, и каждое значение карты должно содержать некоторый набор временных меток для предыдущих событий и, возможно, скользящее среднее текущего «тепла». "для этого типа события, но я не могу понять, как начать реализовывать что-то еще. В частности, мне сложно понять, как перейти от фактического уравнения Ньютона, которое является очень общим, и применить его к этому конкретному сценарию.

Есть ли у кого-нибудь указатели? Может ли кто-нибудь предложить для меня более простой «алгоритм оценки недавности», который можно было бы заменить ньютоновским охлаждением в дороге?

РЕДАКТИРОВАТЬ : Вот код закрытия! Он относится к событиям как к буквам, но, очевидно, может быть перепрофилирован для использования любого другого объекта.

(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)))))
14
задан Ben Englert 12 October 2011 в 14:43
поделиться