/// <summary> /// Implementation to generate the ranking list for the provided set /// of votes for a specific task. /// </summary> /// <param name="task">The task that the votes are grouped under.</param> /// <returns>Returns a ranking list of winning votes.</returns> protected override RankResults RankTask(GroupedVotesByTask task) { if (task == null) { throw new ArgumentNullException(nameof(task)); } RankResults winningChoices = new RankResults(); if (task.Any()) { var voterRankings = GroupRankVotes.GroupByVoterAndRank(task); var allChoices = GroupRankVotes.GetAllChoices(voterRankings); for (int i = 1; i <= 9; i++) { RankResult winner = GetWinningVote(voterRankings, winningChoices); if (winner == null) { break; } winningChoices.Add(winner); allChoices.Remove(winner.Option); if (!allChoices.Any()) { break; } } } return(winningChoices); }
/// <summary> /// Implementation to generate the ranking list for the provided set /// of votes for a specific task. /// </summary> /// <param name="task">The task that the votes are grouped under.</param> /// <returns>Returns a ranking list of winning votes.</returns> protected override RankResults RankTask(GroupedVotesByTask task) { RankResults winningChoices = new RankResults(); // The groupVotes are used for getting the Wilson score var rankedVotes = GroupRankVotes.GroupByVoteAndRank(task); // The voterRankings are used for the runoff var voterRankings = GroupRankVotes.GroupByVoterAndRank(task); // The full choices list is just to keep track of how many we have left. var allChoices = GroupRankVotes.GetAllChoices(voterRankings); for (int i = 1; i <= 9; i++) { RankResult winner = GetWinningVote(voterRankings, rankedVotes); if (winner == null) { break; } winningChoices.Add(winner); allChoices.Remove(winner.Option); if (!allChoices.Any()) { break; } voterRankings = RemoveChoiceFromVotes(voterRankings, winner.Option); rankedVotes = RemoveChoiceFromRanks(rankedVotes, winner.Option); } return(winningChoices); }
public LeaderboardResults GetLeaderboardRankings(int competitionID, int groupID, string userToken, string selectedRank) { //from arry index to data base ID; LeaderboardResults leaderboardResults = new LeaderboardResults(); //ranking results for specific group's specific compentition List <RankResults> rankResults = new List <RankResults>(); if (groupID == -1)//Individual grankings { rankResults = this.individualRankings(competitionID); } else//Groups rankings { rankResults = this.groupRankings(competitionID, groupID); } //sort and rank results leaderboardResults.RankResults = sortAndRank(rankResults, selectedRank); //Current User's results User currentUser = new FeaturesController(_context, null).GetUserByToken(userToken); //find current user in ranking results if (currentUser != null) { for (int i = 0; i < leaderboardResults.RankResults.Count; i++) { if (leaderboardResults.RankResults.ElementAt(i).Username.Equals(currentUser.Username)) { leaderboardResults.UserResults = leaderboardResults.RankResults.ElementAt(i); } } if (leaderboardResults.UserResults == null) { leaderboardResults.UserResults = new RankResults() { Username = currentUser.Username, Best = 0, Total = 0, Average = 0, Rank = 0 }; } } else { RankResults rankResult = new RankResults(); rankResult.Username = "******"; rankResult.Rank = 0; rankResult.Best = 0; rankResult.Total = 0; rankResult.Average = 0; leaderboardResults.UserResults = rankResult; } //final results*/ return(leaderboardResults); }
/// <summary> /// Gets the winning vote. /// Excludes any already chosen votes from the process. /// </summary> /// <param name="voterRankings">The voter rankings.</param> /// <param name="chosenChoices">The already chosen choices.</param> /// <param name="allChoices">All remaining choices.</param> /// <returns>Returns the winning vote.</returns> /// <exception cref="System.ArgumentNullException"> /// </exception> private RankResult GetWinningVote(IEnumerable <VoterRankings> voterRankings, RankResults chosenChoices, List <string> allChoices) { if (voterRankings == null) { throw new ArgumentNullException(nameof(voterRankings)); } if (chosenChoices == null) { throw new ArgumentNullException(nameof(chosenChoices)); } // Initial conversion from enumerable to list List <VoterRankings> localRankings = RemoveChoicesFromVotes(voterRankings, chosenChoices.Select(c => c.Option)); AddUnselectedRankings(localRankings, allChoices); int voterCount = localRankings.Count(); int winCount = voterCount / 2 + 1; string eliminated = ""; bool eliminateOne = false; while (true) { var preferredVotes = GetPreferredCounts(localRankings); if (!preferredVotes.Any()) { break; } ChoiceCount best = preferredVotes.MaxObject(a => a.Count); if (best.Count >= winCount) { return(new RankResult(best.Choice, $"Coombs Eliminations: [{eliminated}]")); } // If no more choice removals will bump up lower prefs to higher prefs, return the best of what's left. if (!localRankings.Any(r => r.RankedVotes.Count() > 1)) { return(new RankResult(best.Choice, $"Coombs Eliminations: [{eliminated}]")); } eliminated += Comma(eliminateOne); string leastPreferredChoice = GetLeastPreferredChoice(localRankings); eliminated += leastPreferredChoice; RemoveChoiceFromVotes(localRankings, leastPreferredChoice); eliminateOne = true; } return(null); }
private List <RankResults> groupRankings(int competitionID, int groupID) { var query = from Group in _context.Groups join UserGroup in _context.UserGroups on Group.Id equals UserGroup.Group.Id join User in _context.Users on UserGroup.User.Id equals User.Id join UserCompetitionTotalScore in _context.UserCompetitionTotalScores on User.Id equals UserCompetitionTotalScore.User.Id join Competition in _context.Competitions on UserCompetitionTotalScore.Competition.Id equals Competition.Id where (UserCompetitionTotalScore.Competition.Id == competitionID && Group.Id == groupID) select new { User.Username, User.Name, User.Surname, User.MemberID, UserCompetitionTotalScore.Average, UserCompetitionTotalScore.Total, UserCompetitionTotalScore.Best }; //saving results in an List which will make sorting easier(ArrayList) int rank = 1; List <RankResults> ranklist = new List <RankResults>(); foreach (var item in query) { if (item.Average > 0 && item.Best > 0) { RankResults rankResult = new RankResults(); rankResult.Username = item.Username; rankResult.DisplayName = getDisplayName(item.Name, item.Surname); rankResult.Best = item.Best; rankResult.Total = item.Total; rankResult.Average = item.Average; rankResult.Rank = rank; if (item.MemberID != null) { rankResult.isMember = true; } else { rankResult.isMember = false; } ranklist.Add(rankResult); rank++; } } //rank and return results return(ranklist); }
/// <summary> /// Implementation to generate the ranking list for the provided set /// of votes for a specific task. /// </summary> /// <param name="task">The task that the votes are grouped under.</param> /// <returns>Returns a ranking list of winning votes.</returns> protected override RankResults RankTask(GroupedVotesByTask task) { var groupVotes = GroupRankVotes.GroupByVoteAndRank(task); var rankedVotes = from vote in groupVotes select new { Vote = vote.VoteContent, Rank = RankVote(vote.Ranks) }; var orderedVotes = rankedVotes.OrderByDescending(a => a.Rank); RankResults results = new RankResults(); results.AddRange(orderedVotes.Select(a => new RankResult(a.Vote, $"BordaRank: [{a.Rank}]"))); return(results); }
/// <summary> /// Gets the winning vote, instant runoff style. /// </summary> /// <param name="voterRankings">The voters' rankings.</param> /// <param name="chosenChoices">The already chosen choices that we should exclude.</param> /// <returns>Returns the winning vote, if any. Otherwise, null.</returns> /// <exception cref="System.ArgumentNullException"> /// </exception> private RankResult GetWinningVote(IEnumerable <VoterRankings> voterRankings, RankResults chosenChoices) { if (voterRankings == null) { throw new ArgumentNullException(nameof(voterRankings)); } if (chosenChoices == null) { throw new ArgumentNullException(nameof(chosenChoices)); } List <VoterRankings> localRankings = RemoveChoicesFromVotes(voterRankings, chosenChoices.Select(c => c.Option)); int voterCount = localRankings.Count(v => v.RankedVotes.Any()); int winCount = voterCount / 2 + 1; string eliminated = ""; bool eliminateOne = false; while (true) { var preferredVotes = GetPreferredCounts(localRankings); if (!preferredVotes.Any()) { break; } var best = preferredVotes.MaxObject(a => a.Count); if (best.Count >= winCount) { return(new RankResult(best.Choice, $"IRV Eliminations: [{eliminated}]")); } var worst = preferredVotes.MinObject(a => a.Count); eliminated += Comma(eliminateOne) + worst.Choice; RemoveChoiceFromVotes(localRankings, worst.Choice); eliminateOne = true; } return(null); }
/// <summary> /// Implementation to generate the ranking list for the provided set /// of votes for a specific task. /// </summary> /// <param name="task">The task that the votes are grouped under.</param> /// <returns>Returns a ranking list of winning votes.</returns> protected override RankResults RankTask(GroupedVotesByTask task) { // Can calculating the score easily by having all the rankings for // each vote grouped together. var groupVotes = GroupRankVotes.GroupByVoteAndRank(task); var rankedVotes = from vote in groupVotes select new { Vote = vote.VoteContent, Rank = RankScoring.LowerWilsonScore(vote.Ranks) }; var orderedVotes = rankedVotes.OrderByDescending(a => a.Rank); RankResults results = new RankResults(); results.AddRange(orderedVotes.Select(a => new RankResult(a.Vote, $"Wilson: [{a.Rank:f5}]"))); return(results); }
/// <summary> /// Implementation to generate the ranking list for the provided set /// of votes for a specific task, based on the Schulze algorithm. /// </summary> /// <param name="task">The task that the votes are grouped under.</param> /// <returns>Returns a ranking list of winning votes.</returns> protected override RankResults RankTask(GroupedVotesByTask task) { if (task == null) throw new ArgumentNullException(nameof(task)); Debug.WriteLine(">>Pairwise Ranking<<"); List<string> listOfChoices = GroupRankVotes.GetAllChoices(task); var voterRankings = GroupRankVotes.GroupByVoterAndRank(task); int[,] pairwisePreferences = GetPairwisePreferences(voterRankings, listOfChoices); int[,] pairwiseWinners = GetPairwiseWinners(pairwisePreferences, listOfChoices.Count); RankResults winningChoices = GetResultsInOrder(pairwiseWinners, listOfChoices); return winningChoices; }
/// <summary> /// Implementation to generate the ranking list for the provided set /// of votes for a specific task. /// </summary> /// <param name="task">The task that the votes are grouped under.</param> /// <returns>Returns a ranking list of winning votes.</returns> protected override RankResults RankTask(GroupedVotesByTask task) { Debug.WriteLine(">>Normalized Borda Counting<<"); //var voterCount = task.SelectMany(t => t.Value).Distinct().Count(); var groupVotes = GroupRankVotes.GroupByVoteAndRank(task); var rankedVotes = from vote in groupVotes select new { Vote = vote.VoteContent, Rank = RankVote(vote.Ranks) }; var orderedVotes = rankedVotes.OrderBy(a => a.Rank); RankResults results = new RankResults(); results.AddRange(orderedVotes.Select(a => new RankResult(a.Vote, $"BordaNorm: [{a.Rank:f5}]"))); return(results); }
/// <summary> /// Implementation to generate the ranking list for the provided set /// of votes for a specific task, based on the Schulze algorithm. /// </summary> /// <param name="task">The task that the votes are grouped under.</param> /// <returns>Returns a ranking list of winning votes.</returns> protected override RankResults RankTask(GroupedVotesByTask task) { if (task == null) { throw new ArgumentNullException(nameof(task)); } List <string> listOfChoices = GroupRankVotes.GetAllChoices(task); var voterRankings = GroupRankVotes.GroupByVoterAndRank(task); int[,] pairwisePreferences = GetPairwisePreferences(voterRankings, listOfChoices); int[,] strongestPaths = GetStrongestPaths(pairwisePreferences, listOfChoices.Count); int[,] winningPaths = GetWinningPaths(strongestPaths, listOfChoices.Count); RankResults winningChoices = GetResultsInOrder(winningPaths, listOfChoices); return(winningChoices); }
/// <summary> /// Gets the winning options in order of preference, based on the winning paths. /// </summary> /// <param name="winningPaths">The winning paths.</param> /// <param name="listOfChoices">The list of choices.</param> /// <returns>Returns a list of </returns> private RankResults GetResultsInOrder(int[,] winningPaths, List <string> listOfChoices) { int count = listOfChoices.Count; var availableIndexes = Enumerable.Range(0, count); var pathCounts = from index in availableIndexes select new { Index = index, Choice = listOfChoices[index], Count = GetPositivePathCount(winningPaths, index, count), Sum = GetPathSum(winningPaths, index, count) }; var orderPaths = pathCounts.OrderByDescending(p => p.Count).ThenByDescending(p => p.Sum).ThenBy(p => p.Choice); RankResults results = new RankResults(); results.AddRange(orderPaths.Select(path => new RankResult(listOfChoices[path.Index], $"Schulze: [{path.Count}/{path.Sum}]"))); return(results); }
/// <summary> /// Implementation to generate the ranking list for the provided set /// of votes for a specific task, based on the Schulze algorithm. /// </summary> /// <param name="task">The task that the votes are grouped under.</param> /// <returns>Returns a ranking list of winning votes.</returns> protected override RankResults RankTask(GroupedVotesByTask task) { if (task == null) { throw new ArgumentNullException(nameof(task)); } Debug.WriteLine(">>Distance U0 Scoring<<"); List <string> listOfChoices = GroupRankVotes.GetAllChoices(task); var voterRankings = GroupRankVotes.GroupByVoterAndRank(task); DistanceData pairwiseData = GetPairwiseData(voterRankings, listOfChoices); DistanceData strengthData = GetStrongestPaths(pairwiseData, listOfChoices.Count); DistanceData winningPaths = GetWinningPaths(strengthData, listOfChoices.Count); RankResults winningChoices = GetResultsInOrder(winningPaths, listOfChoices); return(winningChoices); }
private List <RankResults> individualRankings(int competitionID) { //need to update with Outer join query var query = from User in _context.Users join UserCompetitionTotalScore in _context.UserCompetitionTotalScores on User.Id equals UserCompetitionTotalScore.User.Id where (UserCompetitionTotalScore.Competition.Id == competitionID) select new { User.Username, User.Name, User.Surname, User.MemberID, UserCompetitionTotalScore.Average, UserCompetitionTotalScore.Total, UserCompetitionTotalScore.Best }; var queryAllCustomers = from user in _context.Users select user.Username; List <string> users = queryAllCustomers.ToList <string>(); //saving results in an List which will make sorting easier(ArrayList) List <RankResults> ranklist = new List <RankResults>(); foreach (var item in query) { if (item.Average > 0 && item.Best > 0) { RankResults rankResult = new RankResults(); rankResult.Username = item.Username; rankResult.DisplayName = getDisplayName(item.Name, item.Surname); rankResult.Best = item.Best; rankResult.Total = item.Total; rankResult.Average = item.Average; rankResult.Rank = 0; if (item.MemberID != null) { rankResult.isMember = true; } else { rankResult.isMember = false; } ranklist.Add(rankResult); //remove user from users without scores users.RemoveAll(x => x.Equals(item.Username)); } } for (int i = 0; i < users.Count; i++) { RankResults tempRankResult = new RankResults(); User user = _context.Users.Where(u => u.Username.Equals(users.ElementAt(i))).FirstOrDefault <User>(); tempRankResult.Username = user.Username; tempRankResult.DisplayName = getDisplayName(user.Name, user.Surname); tempRankResult.Total = 0; tempRankResult.Best = 0; tempRankResult.Average = 0; tempRankResult.Rank = 0; ranklist.Add(tempRankResult); } return(ranklist); }