diff --git a/lib/Tumblr/StreamBuilder/StreamRankers/WeightedRandomStreamRanker.php b/lib/Tumblr/StreamBuilder/StreamRankers/WeightedRandomStreamRanker.php index 5fc2d17..2dd17cc 100644 --- a/lib/Tumblr/StreamBuilder/StreamRankers/WeightedRandomStreamRanker.php +++ b/lib/Tumblr/StreamBuilder/StreamRankers/WeightedRandomStreamRanker.php @@ -46,21 +46,44 @@ protected function rank_inner(array $stream_elements, StreamTracer $tracer = nul // weighted sampling array, $H: ['sampling score' => $stream_element] $H = []; - $max_rand = mt_getrandmax(); /** @var StreamElement $element */ foreach ($valid_elements as $element) { - /** @var RecommendationLeafStreamElementTrait $original_element */ - $original_element = $element->get_original_element(); // calculate sampling score - $r = pow(mt_rand() / $max_rand, (1 / $original_element->get_score())); - $H[strval($r)] = $element; + $r = $this->get_element_random_score($element); + + // store the element in $H, using $r as key. + $key = strval($r); + if (array_key_exists($key, $H)) { + // We don't want to replace an element that was previously added to $H. + // so we append the element id, if the key already exists. + $key = sprintf('%s_%s', $key, $element->get_element_id()); + } + $H[$key] = $element; } + // sort by key in descending order krsort($H); $ranked_elements = array_values($H); return array_merge($ranked_elements, $not_valid_elements); } + /** + * @param StreamElement $element Stream element to rank randomly + * @return float|int|object + */ + protected function get_element_random_score(StreamElement $element) + { + /** @var RecommendationLeafStreamElementTrait $original_element */ + $original_element = $element->get_original_element(); + $max_rand = mt_getrandmax(); + $score = $original_element->get_score(); + if ($score == 0.0) { + $score = 0.001; + } + // calculate sampling score + return pow(mt_rand() / $max_rand, (1 / $score)); + } + /** * Selects stream elements that have a score * @param StreamElement[] $stream_elements Stream elements diff --git a/tests/unit/Tumblr/StreamBuilder/StreamRankers/WeightedRandomStreamRankerTest.php b/tests/unit/Tumblr/StreamBuilder/StreamRankers/WeightedRandomStreamRankerTest.php index fcdbc01..01f8372 100644 --- a/tests/unit/Tumblr/StreamBuilder/StreamRankers/WeightedRandomStreamRankerTest.php +++ b/tests/unit/Tumblr/StreamBuilder/StreamRankers/WeightedRandomStreamRankerTest.php @@ -105,6 +105,7 @@ public function test_ranker_with_stream_elements(): void 1234 => 1.0, 2345 => 2.0, 3456 => 3.0, + 4567 => 0.0, ]; $stream_elements = $this->build_blog_stream_elements($bid2score); mt_srand(0);