/** {@inheritDoc} */ @Override public Recommendations<OUT> doRecommend(IN input, Context<OUT, IN> context) { Recommendations<OUT> recommendations = new Recommendations<>(); for (RecommendationEngine<OUT, IN> engine : engines) { if (engine.participationPolicy(context).participate(input, context, recommendations)) { recommendations.merge(engine.recommend(input, context)); } } removeIrrelevant(input, context, recommendations); for (PostProcessor<OUT, IN> postProcessor : postProcessors) { postProcessor.postProcess(recommendations, input, context); } return recommendations; }
/** * Remove recommendations that have no chance of making it to the final selection, because their * score will always be lower than the score of the last returned recommendation, even after post * processing. This is a performance optimisation, so that irrelevant recommendations don't have * to be post-processed. * * @param input input to the recommendation engine. Typically the person or item recommendations * are being computed for. * @param context additional information about the recommendation process. * @param recommendations computed so far. */ private void removeIrrelevant( IN input, Context<OUT, IN> context, Recommendations<OUT> recommendations) { float maxRelativeChange = maxRelativeChange(input, context); if (Float.POSITIVE_INFINITY == maxRelativeChange) { return; } int i = 0; float minScoreInLimit = 0; for (Recommendation<OUT> recommendation : recommendations.get(Integer.MAX_VALUE)) { if (++i == context.config().limit()) { minScoreInLimit = recommendation.getScore().getTotalScore() - maxRelativeChange; } else if (i > context.config().limit() && recommendation.getScore().getTotalScore() < minScoreInLimit) { recommendations.remove(recommendation.getItem()); } } }