You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
3.9 KiB
197 lines
3.9 KiB
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 |
|
}
|
|
|