package model import ( "math" "time" ) // Algorithm Algorithm type Algorithm interface { Score(stat *ReplyStat) *ReplyScore Slots() []int Name() string } /* Origin Algorithm. */ // Origin origin algorithm type Origin struct { name string slots []int } // NewOrigin NewLikeDesc Aogorithm func NewOrigin(name string, slots []int) *Origin { return &Origin{ name: name, slots: slots, } } // Name get name func (o *Origin) Name() string { return o.name } // Slots get slots func (o *Origin) Slots() []int { return o.slots } // Score calc score func (o *Origin) Score(stat *ReplyStat) (rs *ReplyScore) { rs = new(ReplyScore) rs.RpID = stat.RpID if stat.Like < 0 || stat.Reply < 0 || stat.Report < 0 || stat.Hate < 0 { return } score := int64(100 * ((stat.Like + 2) / (stat.Hate + 4 + stat.Report))) score = score<<32 | (int64(stat.Reply) & 0xFFFFFFFF) rs.Score = float64(score) return } /* LikeDesc Algorithm order by like desc. */ // LikeDesc like desc type LikeDesc struct { name string slots []int } // NewLikeDesc NewLikeDesc Aogorithm func NewLikeDesc(name string, slots []int) *LikeDesc { return &LikeDesc{ name: name, slots: slots, } } // Name get name func (l *LikeDesc) Name() string { return l.name } // Slots get slots func (l *LikeDesc) Slots() []int { return l.slots } // Score calc score func (l *LikeDesc) Score(stat *ReplyStat) (rs *ReplyScore) { rs = new(ReplyScore) rs.RpID = stat.RpID rs.Score = float64(stat.Like) return } /* WilsonLHRR wilson algorithm like,reply hate,report */ // WilsonLHRR WilsonLHRR type WilsonLHRR struct { name string slots []int weight *WilsonLHRRWeight } // NewWilsonLHRR NewWilsonLHRR func NewWilsonLHRR(name string, slots []int, weight *WilsonLHRRWeight) *WilsonLHRR { return &WilsonLHRR{ name: name, slots: slots, weight: weight, } } // Name get name func (w *WilsonLHRR) Name() string { return w.name } // Slots get slots func (w *WilsonLHRR) Slots() []int { return w.slots } // Score calc score func (w *WilsonLHRR) Score(stat *ReplyStat) (rs *ReplyScore) { rs = new(ReplyScore) rs.RpID = stat.RpID if stat.Like < 0 || stat.Reply < 0 || stat.Report < 0 || stat.Hate < 0 { return } ups := float64(stat.Like)*w.weight.Like + float64(stat.Reply)*w.weight.Reply downs := float64(stat.Hate)*w.weight.Hate + float64(stat.Report)*w.weight.Report n := ups + downs if n == 0 { return } z := float64(2) p := ups / n rs.Score = (p + math.Pow(z, 2)/(2*n) - (z/(2*n))*math.Sqrt(4*n*(1-p)*p+math.Pow(z, 2))) / (1 + math.Pow(z, 2)/n) return } /* WilsonLHRRFluid wilson algorightm dynamic score by time like,reply hate,report */ // WilsonLHRRFluid WilsonLHRRFluid type WilsonLHRRFluid struct { name string slots []int weight *WilsonLHRRFluidWeight } // NewWilsonLHRRFluid NewWilsonLHRRFluid func NewWilsonLHRRFluid(name string, slots []int, weight *WilsonLHRRFluidWeight) *WilsonLHRRFluid { return &WilsonLHRRFluid{ name: name, slots: slots, weight: weight, } } // Name get name func (w *WilsonLHRRFluid) Name() string { return w.name } // Slots get slots func (w *WilsonLHRRFluid) Slots() []int { return w.slots } func coolDownFunc(weight *WilsonLHRRFluidWeight, duration float64) (coefficient float64) { return 1.5 - (0.5 / (1 + math.Exp(-weight.Slope*(duration)))) } // Score calc score func (w *WilsonLHRRFluid) Score(stat *ReplyStat) (rs *ReplyScore) { rs = new(ReplyScore) rs.RpID = stat.RpID if stat.Like < 0 || stat.Reply < 0 || stat.Report < 0 || stat.Hate < 0 { return } ups := float64(stat.Like)*w.weight.Like + float64(stat.Reply)*w.weight.Reply downs := float64(stat.Hate)*w.weight.Hate + float64(stat.Report)*w.weight.Report n := ups + downs if n == 0 { return } z := float64(2) p := ups / n coefficient := coolDownFunc(w.weight, float64(time.Now().Unix()-int64(stat.ReplyTime))/86400) rs.Score = ((p + math.Pow(z, 2)/(2*n) - (z/(2*n))*math.Sqrt(4*n*(1-p)*p+math.Pow(z, 2))) / (1 + math.Pow(z, 2)/n)) * coefficient return }