Algorithm clojure中使用牛顿冷却的近期图
我正在Clojure中构建一个系统,该系统实时消耗事件,并根据最近收到的类似消息数量对事件进行处理。我想使用基于牛顿冷却的近期评分来实现这一点 换句话说,当一个事件发生时,我希望能够给它分配一个介于1.0(以前从未发生过,或者牛顿方程中的“环境温度”)和10.0(过去一分钟内发生过多次)之间的分数 我对这个数据结构的外观有一个模糊的概念——每个“事件类型”都是一个映射键,每个映射值都应该包含一些以前事件的时间戳集,可能还包含该事件类型当前“热”的运行平均值,但我不太清楚如何开始实现它。具体地说,我很难理解如何从牛顿的实际方程出发,这是非常通用的,并将其应用到这个特定的场景中 有人有什么建议吗?有没有人能建议一个更简单的“近期评分算法”让我开始,它可以被牛顿冷却法所取代 编辑:这里是一些clojure代码!它将事件称为字母,但显然可以重新调整用途,以获取任何其他类型的对象Algorithm clojure中使用牛顿冷却的近期图,algorithm,math,clojure,Algorithm,Math,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)))))
在没有任何事件的情况下,冷却方程的解是指数衰减。假设
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_冷却
1/e=1/(2.718…)
是产生与num\u events\u to\u heat
相当的效果所需的事件数。它可能是一个较大的正值(比如T\u max
或更大?)。请注意,如果5.0
,则每个事件都会将温度重置为num\u events\u to\u heat==1.0
,这不是很有趣,因此该值至少应该大于1T\u max
- 从理论上讲,加热和冷却都不应该分别达到最高和最低温度(假设参数设置如上所述,并且您从这两者之间的某个地方开始)。然而,在实践中,这个过程的指数性质应该足够接近,因为没有区别
- 要实现这一点,您只需要存储上次更新的时间戳和温度。收到事件后,执行冷却步骤,然后执行加热事件,并使用新的温度和时间戳进行更新
- 请注意,只读查询不需要更新:您可以只计算自上次更新以来的制冷量
算法tag.t_冷却是一个“时间常数”——冷却到原始增量的36.8%的时间。这是一个很好的答案。它展示了对点质量冷却物理的良好理解,并以一种新颖的方式应用它。