2011-10-04 16 views
14

Tôi đang xây dựng một hệ thống ở Clojure tiêu thụ các sự kiện theo thời gian thực và tác động lên chúng theo số lượng tin nhắn tương tự đã nhận được gần đây. Tôi muốn thực hiện điều này bằng cách sử dụng một điểm số recency dựa trên Newton làm mát.Bản đồ truy cập trong clojure bằng cách sử dụng Newton cooling

Nói cách khác, khi một sự kiện đến, tôi muốn có thể gán cho nó điểm số từ 1.0 (chưa bao giờ xảy ra trước đó hoặc "nhiệt độ môi trường" trong phương trình Newton) và 10.0 (nóng nóng nóng) trong phút vừa qua).

Tôi có ý tưởng mơ hồ về cấu trúc dữ liệu này - mỗi "loại sự kiện" là khóa bản đồ và mọi giá trị bản đồ phải chứa một số dấu thời gian cho các sự kiện trước đó và có thể là mức trung bình hiện tại " nhiệt "cho loại sự kiện đó, nhưng tôi không thể tìm ra cách để bắt đầu thực hiện vượt quá điều đó. Cụ thể là tôi đang gặp khó khăn trong việc tìm ra cách để đi từ phương trình thực tế của Newton, đó là rất chung chung, và áp dụng nó cho kịch bản cụ thể này.

Có ai có bất kỳ con trỏ nào không? Ai đó có thể đề xuất một thuật toán "thuật toán điểm số" đơn giản hơn để tôi bắt đầu, điều đó có thể được thay thế bằng cách làm nguội Newton xuống đường?

EDIT: Đây là một số mã clojure! Nó đề cập đến các sự kiện như các chữ cái nhưng rõ ràng có thể được định hướng lại để lấy bất kỳ loại đối tượng nào khác.

(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 cho một câu hỏi hay. Tôi sẽ quan tâm để xem câu trả lời bạn nhận được. –

+0

+1 quá. Và chỉ cần thêm thẻ 'thuật toán'. – 4e6

Trả lời

5

Không có bất kỳ sự kiện nào, giải pháp cho phương trình làm mát là phân rã theo cấp số nhân. Nói T_0 là nhiệt độ ở phần đầu của một giai đoạn làm mát, và dt là timestep (tính từ thời gian hệ thống hoặc bất cứ điều gì) kể từ khi bạn đánh giá nhiệt độ là T_0:

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

Kể từ khi sự kiện của bạn là xung rời rạc, và bạn có một nhiệt độ tối đa, bạn muốn có một tỷ lệ nhất định cho mỗi sự kiện:

T_post_event = T_pre_event + (T_max - T_pre_event)/num_events_to_heat 

một số lưu ý:

  • t_cooling là thời gian để mọi thứ nguội đi theo hệ số 1/e = 1/(2.718...).

  • num_events_to_heat là số sự kiện cần thiết để có hiệu lực tương đương với T_max. Nó có thể là một giá trị dương lớn vừa phải (nói 5.0 hoặc nhiều hơn?). Lưu ý rằng nếu num_events_to_heat==1.0, mọi sự kiện sẽ đặt lại nhiệt độ thành T_max, điều này không thú vị lắm, vì vậy giá trị ít nhất phải lớn hơn một.

  • Về mặt lý thuyết, cả sưởi ấm và làm mát không bao giờ nên đạt tới nhiệt độ tối đa và tối thiểu, tương ứng (các tham số giả định được đặt ở trên và bạn đang bắt đầu ở đâu đó ở giữa). Tuy nhiên, trong thực tế, tính chất theo cấp số nhân của quy trình phải đủ gần như không tạo ra sự khác biệt ...

  • Để thực hiện việc này, bạn chỉ cần lưu dấu thời gian và nhiệt độ của lần cập nhật cuối cùng. Khi bạn nhận được một sự kiện, làm một bước làm mát, sau đó một sự kiện sưởi ấm, và cập nhật với nhiệt độ và dấu thời gian mới.

  • Lưu ý rằng các truy vấn chỉ đọc không yêu cầu cập nhật: bạn chỉ có thể tính toán làm mát kể từ lần cập nhật cuối cùng.

+0

t_cooling là "hằng số thời gian" - thời gian làm mát đến 36,8% đồng bằng gốc. Đây là một câu trả lời tuyệt vời. Nó cho thấy một nắm bắt tốt về vật lý làm mát một khối điểm và áp dụng nó theo một cách mới lạ. – duffymo

Các vấn đề liên quan