Exemplo n.º 1
0
        /// <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>
        /// <returns>Returns the winning vote.</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));
            }

            // Initial conversion from enumerable to list
            List <VoterRankings> localRankings = RemoveChoicesFromVotes(voterRankings, chosenChoices.Select(c => c.Option));

            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, $"Baldwin 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, $"Baldwin Eliminations: [{eliminated}]"));
                }

                string leastPreferredChoice = GetLeastPreferredChoice(localRankings);

                eliminated += Comma(eliminateOne) + leastPreferredChoice;

                RemoveChoiceFromVotes(localRankings, leastPreferredChoice);
                eliminateOne = true;
            }

            return(null);
        }
Exemplo n.º 2
0
        /// <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);
        }