64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
package ctxmgr
|
|
|
|
import (
|
|
"math"
|
|
"time"
|
|
)
|
|
|
|
// CalculateDecayedWeight 计算考虑时间半衰期与里程碑豁免后的有效权重
|
|
func CalculateDecayedWeight(rawWeight float64, createdAt time.Time, isMilestone bool, cfg TimeDecayConfig) float64 {
|
|
if rawWeight <= 0 {
|
|
rawWeight = 1.00
|
|
}
|
|
if !cfg.Enabled {
|
|
return rawWeight
|
|
}
|
|
// 里程碑事件豁免衰减,作为永久基石
|
|
if isMilestone && cfg.MilestoneExempt {
|
|
return rawWeight
|
|
}
|
|
|
|
halfLife := cfg.HalfLifeDays
|
|
if halfLife <= 0 {
|
|
halfLife = 7.0
|
|
}
|
|
|
|
daysDiff := time.Since(createdAt).Hours() / 24.0
|
|
if daysDiff <= 0 {
|
|
return rawWeight
|
|
}
|
|
|
|
lambda := math.Ln2 / halfLife
|
|
decayFactor := math.Exp(-lambda * daysDiff)
|
|
|
|
decayed := rawWeight * decayFactor
|
|
|
|
// 应用衰减下限保护,防止早期有价值信息完全被截断
|
|
floor := rawWeight * cfg.MinWeightFloor
|
|
if decayed < floor {
|
|
decayed = floor
|
|
}
|
|
|
|
return math.Round(decayed*1000) / 1000
|
|
}
|
|
|
|
// ApplyTimeDecayToActivities 对活动流批量应用时间衰减并按最终有效权重重排
|
|
func ApplyTimeDecayToActivities(items []ActivityItem, cfg TimeDecayConfig) []ActivityItem {
|
|
res := make([]ActivityItem, len(items))
|
|
for i, it := range items {
|
|
it.DecayedWeight = CalculateDecayedWeight(it.RawWeight, it.CreatedAt, it.IsMilestone, cfg)
|
|
res[i] = it
|
|
}
|
|
|
|
// 稳定排序:按 DecayedWeight 降序,相同时按时间倒序
|
|
for i := 0; i < len(res); i++ {
|
|
for j := i + 1; j < len(res); j++ {
|
|
if res[j].DecayedWeight > res[i].DecayedWeight ||
|
|
(res[j].DecayedWeight == res[i].DecayedWeight && res[j].CreatedAt.After(res[i].CreatedAt)) {
|
|
res[i], res[j] = res[j], res[i]
|
|
}
|
|
}
|
|
}
|
|
return res
|
|
}
|