public IEnumerable <IRating> RecommendSubjects(IRater rater, IEnumerable <ISubject> subjects, int take = -1, int skip = 0) { var cachedResults = new ConcurrentBag <IRating>(); var notCachedSubjects = new ConcurrentBag <ISubject>(); var options = new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }; Parallel.ForEach(subjects, options, subject => { var key = CreateCacheKey(rater, subject); var value = 0D; if (_cache.TryGetValue(key, out value)) { var ranking = new SimpleRating(rater, subject, value); cachedResults.Add(ranking); } else { notCachedSubjects.Add(subject); } }); var partial = _algorithm.RecommendSubjects(rater, notCachedSubjects); var results = partial.ToList(); results.AddRange(cachedResults); var sorted = results.OrderByDescending(p => p.Value).AsEnumerable(); if (skip > 0) { sorted = sorted.Skip(skip); } if (take > 0) { sorted = sorted.Take(take); } return(sorted); }
public override double CalculateError(IRecommendation recommendation, IEnumerable <IRating> ratings, IEnumerable <IRater> raters, IEnumerable <ISubject> subjects) { double error = 0.0; foreach (var rater in raters) { var topList = recommendation.RecommendSubjects(rater, subjects, 0, 10); foreach (var result in topList) { if (!ratings.Any(r => r.Subject == result.Subject && r.Rater == result.Rater)) { error += 1.0; } } } return(error); }