Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm clojure中使用牛顿冷却的近期图_Algorithm_Math_Clojure - Fatal编程技术网

Algorithm clojure中使用牛顿冷却的近期图

Algorithm clojure中使用牛顿冷却的近期图,algorithm,math,clojure,Algorithm,Math,Clojure,我正在Clojure中构建一个系统,该系统实时消耗事件,并根据最近收到的类似消息数量对事件进行处理。我想使用基于牛顿冷却的近期评分来实现这一点 换句话说,当一个事件发生时,我希望能够给它分配一个介于1.0(以前从未发生过,或者牛顿方程中的“环境温度”)和10.0(过去一分钟内发生过多次)之间的分数 我对这个数据结构的外观有一个模糊的概念——每个“事件类型”都是一个映射键,每个映射值都应该包含一些以前事件的时间戳集,可能还包含该事件类型当前“热”的运行平均值,但我不太清楚如何开始实现它。具体地说,

我正在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)))))

在没有任何事件的情况下,冷却方程的解是指数衰减。假设
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
    ,则每个事件都会将温度重置为
    T\u max
    ,这不是很有趣,因此该值至少应该大于1

  • 从理论上讲,加热和冷却都不应该分别达到最高和最低温度(假设参数设置如上所述,并且您从这两者之间的某个地方开始)。然而,在实践中,这个过程的指数性质应该足够接近,因为没有区别

  • 要实现这一点,您只需要存储上次更新的时间戳和温度。收到事件后,执行冷却步骤,然后执行加热事件,并使用新的温度和时间戳进行更新

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


+1问一个好问题。我很想看看你得到的答案。刚刚添加了
算法
tag.t_冷却是一个“时间常数”——冷却到原始增量的36.8%的时间。这是一个很好的答案。它展示了对点质量冷却物理的良好理解,并以一种新颖的方式应用它。