add web service
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"math/rand/v2"
|
||||
"time"
|
||||
|
||||
"git.vakhrushev.me/av/remembos/internal/memos"
|
||||
)
|
||||
|
||||
// Memory is the result of the search algorithm.
|
||||
type Memory struct {
|
||||
Memo *memos.Memo
|
||||
Tier int
|
||||
YearsAgo int
|
||||
ShowCount int
|
||||
Date time.Time
|
||||
}
|
||||
|
||||
// candidate is an intermediate struct during scoring.
|
||||
type candidate struct {
|
||||
memo *memos.Memo
|
||||
yearsAgo int
|
||||
showCount int
|
||||
}
|
||||
|
||||
// weightedSelect picks one candidate using weighted random selection.
|
||||
// preferOlder gives higher weight to older memos. maxYearsBack normalizes recency.
|
||||
func weightedSelect(candidates []candidate, preferOlder bool, maxYearsBack int) *candidate {
|
||||
if len(candidates) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(candidates) == 1 {
|
||||
return &candidates[0]
|
||||
}
|
||||
|
||||
scores := make([]float64, len(candidates))
|
||||
var total float64
|
||||
|
||||
for i, c := range candidates {
|
||||
var recencyFactor float64
|
||||
if preferOlder && maxYearsBack > 0 && c.yearsAgo > 0 {
|
||||
recencyFactor = float64(c.yearsAgo) / float64(maxYearsBack)
|
||||
} else {
|
||||
recencyFactor = 1.0
|
||||
}
|
||||
|
||||
showCountPenalty := 1.0 / (1.0 + float64(c.showCount))
|
||||
|
||||
score := recencyFactor * showCountPenalty
|
||||
if score < 0.01 {
|
||||
score = 0.01 // minimum weight
|
||||
}
|
||||
scores[i] = score
|
||||
total += score
|
||||
}
|
||||
|
||||
r := rand.Float64() * total
|
||||
var cumulative float64
|
||||
for i, s := range scores {
|
||||
cumulative += s
|
||||
if r <= cumulative {
|
||||
return &candidates[i]
|
||||
}
|
||||
}
|
||||
|
||||
return &candidates[len(candidates)-1]
|
||||
}
|
||||
Reference in New Issue
Block a user