Sto costruendo un sistema in Clojure che consuma eventi in tempo reale e agisce su di loro in base a quanti messaggi simili sono stati ricevuti di recente. Vorrei implementarlo utilizzando un punteggio di recency basato sul raffreddamento newtoniano.Mappa di recency in clojure usando il raffreddamento newtoniano
In altre parole, quando arriva un evento, voglio essere in grado di assegnargli un punteggio compreso tra 1.0 (mai accaduto prima, o "temperatura ambiente" nell'equazione di Newton) e 10.0 (caldo caldo, si è verificato più volte nel minuto passato).
Ho una vaga idea di come sia questa struttura dati - ogni "tipo di evento" è una chiave di mappa, e ogni valore di mappa dovrebbe contenere un certo numero di timestamp per eventi precedenti e forse una media corrente dell'attuale " calore "per quel tipo di evento, ma non riesco a capire come iniziare ad implementare oltre questo. In particolare, ho difficoltà a capire come passare dall'equazione attuale di Newton, che è molto generica, e applicarla a questo specifico scenario.
Qualcuno ha qualche indicazione? Qualcuno potrebbe suggerire un "algoritmo del punteggio di recency" più semplice per iniziare, che potrebbe essere sostituito da Newtonian che si raffredda lungo la strada?
MODIFICA: Ecco alcuni codice del clojure! Si riferisce agli eventi come lettere ma potrebbe ovviamente essere riproposto per prendere qualsiasi altro tipo di oggetto.
(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)))))
+1 per una grande domanda. Sarò interessato a vedere le risposte che ottieni. –
+1. E ha appena aggiunto il tag 'algorithm'. – 4e6