protected override Pair ProcessRatings(IRating firstRating, IRating secondRating) { var pair = new Pair() { FirstRating = firstRating, SecondRating = secondRating }; if (firstRating.Subject.Id == secondRating.Subject.Id) { ++IndexFirst; ++IndexSecond; } else if (firstRating.Subject.Id < secondRating.Subject.Id) { var rating = new SimpleRating(firstRating.Rater, firstRating.Subject, _defaultValue); pair.FirstRating = rating; ++IndexFirst; } else { var rating = new SimpleRating(secondRating.Rater, secondRating.Subject, _defaultValue); pair.SecondRating = rating; ++IndexSecond; } return(pair); }
private IEnumerable <Pair> GetRatingTail(ref int index, int count, IEnumerable <IRating> ratings, IRater rater, bool isSecondFake) { var list = new LinkedList <Pair>(); while (index < count) { var rating = ratings.ElementAt(index); var ratingFake = new SimpleRating(rater, rating.Subject, _defaultValue); var pair = isSecondFake ? new Pair() { FirstRating = rating, SecondRating = ratingFake } : new Pair() { FirstRating = ratingFake, SecondRating = rating }; ++index; list.AddLast(pair); } return(list); }
public virtual IRating RecommendSubject(IRater rater, ISubject subject) { var alreadyRated = Ratings.Find(p => p.Rater.Id == rater.Id && p.Subject.Id == subject.Id); if (alreadyRated != null) { return(alreadyRated); } var ratings = Ratings.Where(p => p.Subject.Id == subject.Id && p.Rater.Id != rater.Id).ToList(); if (!ratings.Any()) { return(null); } var meanVote = RatersMeanVote(rater); var options = new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }; var sumBag = new ConcurrentBag <decimal>(); var weightSumBag = new ConcurrentBag <decimal>(); Parallel.ForEach(ratings, options, rating => { try { var weight = Weight(rater, rating.Rater); var mean = RatersMeanVote(rating.Rater); var value = (decimal)rating.Value; var diff = value - mean; var val = weight * diff; weightSumBag.Add(weight); sumBag.Add(val); } catch (Exception) { } }); var sum = sumBag.Sum(); var weightSum = weightSumBag.Sum(); if (weightSum == 0) { return(null); } var kappa = 1 / weightSum; var result = meanVote + kappa * sum; var res = (double)result; var rate = new SimpleRating(rater, subject, res); return(rate); }