2012-08-07 42 views
2

我根據在Reddit上的模型,這裏正在爲後系統時間衰減算法: http://amix.dk/blog/post/19588不好計算,以C#端口

我的工作端口是在這裏:

public class Calculation 
{ 
    protected DateTime Epoch = new DateTime(1970, 1, 1); 

    protected long EpochSeconds(DateTime dt) 
    { 
     var ts = dt.Subtract(Convert.ToDateTime("1/1/1970 8:00:00 AM")); 

     return ((((((ts.Days * 24) + ts.Hours) * 60) + ts.Minutes) * 60) + ts.Seconds); 
    } 

    protected int Score(int upVotes, int downVotes) 
    { 
     return upVotes - downVotes; 
    } 

    public double HotScore(int upVotes, int downVotes, DateTime date) 
    { 
     var s = Score(upVotes, downVotes); 
     var order = Math.Log(Math.Max(Math.Abs(s), 1), 10); 
     var sign = Math.Sign(s); 
     var seconds = EpochSeconds(date) - 1134028003; 
     return Math.Round(order + sign * ((double)seconds/45000), 7); 
    } 
} 

基礎的從所提供鏈接的模型輸出中,我會看到0-13小時的逐漸衰減,並在此之後大幅衰減。

我所看到的是非常均勻的衰減,並且得分遠高於原始代碼的輸出(原始代碼:3480-3471)。

這裏是我是如何測試:

 Calculation c = new Calculation(); 
     double now = c.HotScore(100, 2, DateTime.Now); 
     double fivehoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-5)); 
     double tenhoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-10)); 
     double elevenhoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-11)); 
     double twelvehoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-12)); 
     double thirteenhoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-13)); 
     double fiftyhoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-50)); 
     double onehundredhoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-100)); 
     Console.WriteLine(now.ToString()); 
     Console.WriteLine(fivehoursago.ToString()); 
     Console.WriteLine(tenhoursago.ToString()); 
     Console.WriteLine(elevenhoursago.ToString()); 
     Console.WriteLine(twelvehoursago.ToString()); 
     Console.WriteLine(thirteenhoursago.ToString()); 
     Console.WriteLine(fiftyhoursago.ToString()); 
     Console.WriteLine(onehundredhoursago.ToString()); 
     Console.ReadLine(); 

輸出值:

now:    4675.2993816 
five hours:  4674.8993816 
ten hours:   4674.4993816 
eleven hours:  4674.4193816 
twelve hours:  4674.3393816 
thirteen hours: 4674.2593816 
fifty hours:  4671.2993816 
one-hundred hours: 4667.2993816 

顯然這有點工作的權利,但事情是關閉的。這可能與缺乏真正的nix Epoch支持有關,或者缺乏類似的微秒計算,但有些不完全正確。

可能的參考資源: http://blogs.msdn.com/b/brada/archive/2004/03/20/93332.aspx http://codeclimber.net.nz/archive/2007/07/10/convert-a-unix-timestamp-to-a-.net-datetime.aspx

回答

3

你的主要問題是熱算法是時間相關的。您計算的熱門分數爲DateTime.Now,而該文章寫於2010年11月23日(請看文章底部)。

隨着一些試驗和錯誤,似乎數據計算在大約2010-11-23 07:35。嘗試使用該值而不是DateTime.Now,並且應該得到與所示圖表中的數據大致相同的結果。

你要知道,你可以作如下改進你的代碼:

public class Calculation 
{ 
    private static readonly DateTime Epoch = new DateTime(1970, 1, 1); 

    private double EpochSeconds(DateTime dt) 
    { 
     return (dt - Epoch).TotalSeconds; 
    } 

    private int Score(int upVotes, int downVotes) 
    { 
     return upVotes - downVotes; 
    } 

    public double HotScore(int upVotes, int downVotes, DateTime date) 
    { 
     int s = Score(upVotes, downVotes); 
     double order = Math.Log(Math.Max(Math.Abs(s), 1), 10); 
     int sign = Math.Sign(s); 
     double seconds = EpochSeconds(date) - 1134028003; 
     return Math.Round(order + sign * seconds/45000, 7); 
    } 
} 

我的結果:

3479.0956039 
3478.6956039 
3478.2956039 
3478.2156039 
3478.1356039 
3478.0556039 
3475.0956039 
3471.0956039 

變化:

  • 使用的已聲明時代,而不是一個轉換1970-01-01 08:00:00(我認爲08:00是一個錯誤)。
  • 您可以使用a - b減去兩個日期;這與a.Subtract(b)相同,但更簡潔,它反映了原始的Python代碼。
  • 一個時間跨度確實給你微秒的精度(蜱是最小的單位,等於100納秒)。
  • 此外,TotalSeconds給你一個時間跨度內的總秒數;不需要重新計算。小數部分甚至爲您提供微秒精度。
  • 通過從EpochSeconds中返回double,您可以保持這種精度。
  • 使數據類型明確而不是var清楚地指出什麼變量是什麼(它們匹配方法簽名,因此沒有隱式的上傳)。
  • 更改不需要的protectedprivate並使Epoch恆定。
+0

只需要從工作中回來驗證,但讓我說謝謝你花了這麼多時間在這。我知道回答簡短的問題會更容易:) – Wesley 2012-08-08 02:36:24