Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
csimplestring committed Nov 3, 2021
1 parent 940cd24 commit 61732a8
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 0 deletions.
7 changes: 7 additions & 0 deletions ad.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

type Ad interface {
Features() []Feature
Weight(Feature) float32
Bid() float32
}
36 changes: 36 additions & 0 deletions feature.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package main

var endOfPosting PagePostingItem = PagePostingItem{
PID: lastPID,
}

type PagePostingItem struct {
PID int64
Weight float32
}

type PagePostingList struct {
// the end of posting items must be endOfPostingItem
Items []PagePostingItem
// meta info
MaxWeight float32
}

type Feature string // 特征名称,包含特征值?

type FeatureCursor struct {
feature Feature
posting *PagePostingList
current int
}

func (c *FeatureCursor) CurrentPage() PagePostingItem {
return c.posting.Items[c.current]
}

func (c *FeatureCursor) Beyond(PID int64) {
// page IDs are sorted in non-decreasing order
for c.CurrentPage().PID < PID {
c.current++
}
}
133 changes: 133 additions & 0 deletions forecast.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package main

import "sort"

type ImpressionForecastor struct {
pages map[int64]PageMeta
featureToPages map[Feature]*PagePostingList
}

func (i *ImpressionForecastor) forecast(ad Ad) int {
impressions := 0

searcher := &Searcher{
pages: i.pages,
feature2Pages: i.featureToPages,
currentPage: 0,
ad: ad,
}

searcher.initCursors()
pageID := searcher.nextCandidate()
for pageID < lastPID {
p := i.pages[pageID]
score := i.score(ad, p)
if score > p.minScore {
impressions += p.impressions
}
pageID = searcher.nextCandidate()
}

return impressions
}

func (i *ImpressionForecastor) score(ad Ad, page PageMeta) float32 {
pageWeight := make(map[Feature]float32, len(page.features))
for i, f := range page.features {
pageWeight[f] = page.weights[i]
}

sim := float32(0)
for _, f := range ad.Features() {
sim += pageWeight[f] * ad.Weight(f)
}

return sim * ad.Bid()
}

type Searcher struct {
pages map[int64]PageMeta
feature2Pages map[Feature]*PagePostingList

currentPage int64
ad Ad
features []*FeatureCursor
}

func (s *Searcher) initCursors() {
s.currentPage = 0

ad := s.ad
features := ad.Features()
cursors := make([]*FeatureCursor, len(features))
for i, f := range features {

cursors[i] = &FeatureCursor{
feature: f,
posting: s.feature2Pages[f],
current: 0,
}
}

s.features = cursors
}

func (s *Searcher) nextCandidate() int64 {
for {

s.sortFeatures(s.features)
pivot := s.findPivotFeature(s.features)

if pivot == -1 {
return lastPID
}
pivotPID := s.features[pivot].CurrentPage().PID
if pivotPID == lastPID {
return lastPID
}

if pivotPID == s.currentPage {
f := s.pickFeature(s.features[0 : pivot+1])
s.features[f].Beyond(pivotPID + 1)
} else {
if s.features[0].CurrentPage().PID == pivotPID {
s.currentPage = pivotPID
return s.currentPage
} else {
f := s.pickFeature(s.features[0 : pivot+1])
s.features[f].Beyond(pivotPID)
}
}
}
}

func (s *Searcher) sortFeatures(features []*FeatureCursor) {
sort.Slice(features, func(i, j int) bool {
return features[i].CurrentPage().PID < features[j].CurrentPage().PID
})
}

func (s *Searcher) findPivotFeature(cursors []*FeatureCursor) int {
n := len(cursors)
ub := float32(0)
ad := s.ad

minScoreP := s.pages[s.currentPage].minScore
threshold := minScoreP / ad.Bid()

for i := 0; i < n; i++ {

f := cursors[i].feature
maxWeight := s.feature2Pages[f].MaxWeight
ub += ad.Weight(f) * maxWeight
if ub >= threshold {
return i
}
}

return -1
}

func (s *Searcher) pickFeature(cursors []*FeatureCursor) int {
return 0
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/csimplestring/ca-imp-forecast

go 1.17
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
github.com/allegro/bigcache/v3 v3.0.0/go.mod h1:t5TAJn1B9qvf/VlJrSM1r6NlFAYoFDubYUsCuIO9nUQ=
github.com/csimplestring/go-left-right v0.0.3/go.mod h1:ASS5AW8dwk3v6VxpOPQ6wI/N68ibyAMAPW1VTAWQpx8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/linxGnu/go-adder v0.2.0/go.mod h1:t9zC6P+vQpG5iEtw4sinwsVqe52AuFvL4P1dVXHD46c=
github.com/philpearl/stringbank v1.1.0/go.mod h1:0V0f9Ba79DpIl4FTfotL+7IJ+etELdRQIcHJY2nX/+w=
github.com/philpearl/symboltab v1.1.4/go.mod h1:vOdgHoGZAUqGg1apOcrqjuAxFERPUJ03PLfL6pvxNBg=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/valyala/fastrand v1.0.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ=
15 changes: 15 additions & 0 deletions page.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import (
"math"
)

// PageID is generated by increasing order of minScore: smaller ID, smaller score
const lastPID = math.MaxInt64

type PageMeta struct {
impressions int
minScore float32
features []Feature
weights []float32
}

0 comments on commit 61732a8

Please sign in to comment.