likes 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58af381a556319bc76bbc45920a35ab2dcae39c9
|
4
|
+
data.tar.gz: 9b9abb9348acc601d2fe6439667502d9976f6d49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5d316f21c3e6bfd5f2b0d539615d6e136bd05d92e729d051dcb9105b1280cce2831ebc0a55d22e184ea485a273dfd035d519cb6294ec6fbf6f422a09482f91f
|
7
|
+
data.tar.gz: 537f9e0c770cc4ef77c9864acb1e0c4650d39cbf51d9c96aa5fe82312a6992e7ce3711af51bbdefeb63cec37c9901837e2c47fdc4d3c6647a9dc8b112c90c70a
|
@@ -38,6 +38,7 @@ module Likes
|
|
38
38
|
@liked = liked
|
39
39
|
@items = liked.keys
|
40
40
|
@people = likes_of.keys
|
41
|
+
@similarity_limit = INFINITY
|
41
42
|
end
|
42
43
|
|
43
44
|
# Solves the problem and returns recommendation list
|
@@ -53,7 +54,7 @@ module Likes
|
|
53
54
|
private
|
54
55
|
|
55
56
|
attr_reader :person, :likes_of, :liked, :items, :people,
|
56
|
-
:signature, :hash_functions, :hashes
|
57
|
+
:signature, :hash_functions, :hashes, :similarity_limit
|
57
58
|
|
58
59
|
def init_signature
|
59
60
|
@signature = (0...MAX_HASH_FUNCTIONS_COUNT).map {
|
@@ -99,21 +100,41 @@ module Likes
|
|
99
100
|
end
|
100
101
|
|
101
102
|
def best_similarity
|
102
|
-
similarities.
|
103
|
+
@_best_similarity ||= similarities.
|
104
|
+
values.
|
105
|
+
select { |similarity| similarity < similarity_limit }.
|
106
|
+
max
|
103
107
|
end
|
104
108
|
|
105
109
|
def candidates
|
110
|
+
return [] unless best_similarity
|
106
111
|
Hash[similarities.select { |_, similarity|
|
107
112
|
best_similarity <= similarity * ALLOW_FLUCTUATION
|
108
113
|
}].keys
|
109
114
|
end
|
110
115
|
|
111
116
|
def recommendations
|
117
|
+
return [] if candidates.empty?
|
118
|
+
non_empty_recommendations(recommendations_candidate)
|
119
|
+
end
|
120
|
+
|
121
|
+
def recommendations_candidate
|
112
122
|
candidates.map { |other_person, _|
|
113
123
|
likes_of.fetch(other_person) - own_likes
|
114
124
|
}.flatten.uniq
|
115
125
|
end
|
116
126
|
|
127
|
+
def non_empty_recommendations(solution)
|
128
|
+
return next_recommendations if solution.empty?
|
129
|
+
solution
|
130
|
+
end
|
131
|
+
|
132
|
+
def next_recommendations
|
133
|
+
@similarity_limit = best_similarity
|
134
|
+
@_best_similarity = nil
|
135
|
+
recommendations
|
136
|
+
end
|
137
|
+
|
117
138
|
# Full complexity: D * O(likeset size * log N) ~ O(N log N) with big constant
|
118
139
|
def compute_signature
|
119
140
|
each_like do |_, _, row, column|
|
@@ -130,11 +151,16 @@ module Likes
|
|
130
151
|
|
131
152
|
def each_column_of_likes(item, row, &blk)
|
132
153
|
# only columns with 1 in matrix:
|
133
|
-
liked.fetch(item).
|
134
|
-
blk[item, person, row,
|
154
|
+
liked.fetch(item).each do |person|
|
155
|
+
blk[item, person, row, person_column(person)]
|
135
156
|
end
|
136
157
|
end
|
137
158
|
|
159
|
+
def person_column(person)
|
160
|
+
@_person_column ||= {}
|
161
|
+
@_person_column[person] ||= people.index(person)
|
162
|
+
end
|
163
|
+
|
138
164
|
# Complexity: D * O(1)
|
139
165
|
def signature_step(row, column)
|
140
166
|
signature.each_with_index do |signature_row, index|
|
data/lib/likes/version.rb
CHANGED
@@ -19,8 +19,8 @@ module Likes
|
|
19
19
|
context "when somebody literally likes everything" do
|
20
20
|
let(:raw_likeset) { Fixtures.somebody_likes_literally_everything }
|
21
21
|
|
22
|
-
it "
|
23
|
-
expect(likeset.recommendations_for(1).sort).to eq([4, 9])
|
22
|
+
it "does not choose this person as a candidate for recommendations" do
|
23
|
+
expect(likeset.recommendations_for(1).sort).to eq([4, 9])
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|