1package rank
 2
 3import (
 4	"math"
 5)
 6
 7// Algorithm interface and its methods make possible the polimorf usage of
 8// weighting process.
 9type Algorithm interface {
10	WeightingRelation(
11		word1ID int,
12		word2ID int,
13		rank *Rank,
14	) float32
15
16	WeightingHits(
17		wordID int,
18		rank *Rank,
19	) float32
20}
21
22// AlgorithmDefault struct is the basic implementation of Algorithm. It can
23// weight a word or phrase by comparing them.
24type AlgorithmDefault struct{}
25
26// NewAlgorithmDefault constructor retrieves an AlgorithmDefault pointer.
27func NewAlgorithmDefault() *AlgorithmDefault {
28	return &AlgorithmDefault{}
29}
30
31// WeightingRelation method is the traditional algorithm of text rank to
32// weighting a phrase.
33func (a *AlgorithmDefault) WeightingRelation(
34	word1ID int,
35	word2ID int,
36	rank *Rank,
37) float32 {
38	relationQty := rank.Relation.Node[word1ID][word2ID].Qty
39
40	return float32(relationQty)
41}
42
43// WeightingHits method ranks the words by their occurrence.
44func (a *AlgorithmDefault) WeightingHits(
45	wordID int,
46	rank *Rank,
47) float32 {
48	weight := rank.Words[wordID].Qty
49
50	return float32(weight)
51}
52
53// AlgorithmChain struct is the combined implementation of Algorithm. It is a
54// good example how weighting can be changed by a different implementations. It
55// can weight a word or phrase by comparing them.
56type AlgorithmChain struct{}
57
58// NewAlgorithmChain constructor retrieves an AlgorithmChain pointer.
59func NewAlgorithmChain() *AlgorithmChain {
60	return &AlgorithmChain{}
61}
62
63// WeightingRelation method is a combined algorithm of text rank and word
64// occurrence, it weights a phrase.
65func (a *AlgorithmChain) WeightingRelation(
66	word1ID int,
67	word2ID int,
68	rank *Rank,
69) float32 {
70	relationQty := rank.Relation.Node[word1ID][word2ID].Qty
71	word1Qty := rank.Words[word1ID].Qty
72	word2Qty := rank.Words[word2ID].Qty
73
74	qDiff := float32(math.Abs(float64(word1Qty)-float64(word2Qty))) / 100
75	weight := float32(relationQty) + qDiff
76
77	return weight
78}
79
80// WeightingHits method ranks the words by their occurrence.
81func (a *AlgorithmChain) WeightingHits(
82	wordID int,
83	rank *Rank,
84) float32 {
85	word := rank.Words[wordID]
86	qty := 0
87
88	for leftWordID, leftWordQty := range word.ConnectionLeft {
89		qty += rank.Words[leftWordID].Qty * leftWordQty
90	}
91
92	for rightWordID, rightWordQty := range word.ConnectionRight {
93		qty += rank.Words[rightWordID].Qty * rightWordQty
94	}
95
96	weight := float32(word.Qty) + (float32(qty))
97
98	return float32(weight)
99}