public void TestExplicitCreation3()
 {
     var p = new Person(2, 0, 1);
     Assert.AreEqual(1, p.Ranking(0), "Rank of 0");
     Assert.AreEqual(0, p.Ranking(1), "Rank of 1");
     Assert.AreEqual(2, p.Ranking(2), "Rank of 2");
 }
        public void TestNotFirstStep()
        {
            var people = new Person[] { new Person(0, 1, 2) };
            var old = new CandiateRanking[][] { };

            var s = new ESKeepThoseBetterThan(0.5);
            s.RunStep(people, old);
        }
 public void TestExplicitCreation1()
 {
     var p = new Person(0);
     Assert.AreEqual(1, p.FullRanking().Count(), "single candidate, not ranked");
     Assert.AreEqual(0, p.FullRanking().First().candidate, "first candidate");
     Assert.AreEqual(0, p.FullRanking().First().ranking, "first candidate ranking");
     Assert.AreEqual(0, p.Ranking(0), "first candidate direct ranking");
 }
        /// <summary>
        /// Run the election
        /// </summary>
        /// <param name="people"></param>
        /// <param name="previousResults"></param>
        /// <returns></returns>
        public CandiateRanking[] RunStep(Person[] people, CandiateRanking[][] previousResults)
        {
            if (previousResults == null || previousResults.Length == 0)
                throw new InvalidOperationException("Can't run a Keep Best N candidates election step as first step in an election!");

            return (from r in previousResults.Last()
                    orderby r.ranking descending
                    select r).Take((int)CandidatesToKeep).ToArray();
        }
        public void TestSimpleElection()
        {
            var p1 = new Person(0, 1, 2);
            var p2 = new Person(0, 2, 1);

            var r = RunStep(p1, p2);

            Assert.AreEqual(1, r.Length, "# of rankings that came back");
            Assert.AreEqual(2, r.Where(c => c.candidate == 0).First().ranking, "# of votes for candidate 0");
        }
 /// <summary>
 /// Run the election itself.
 /// </summary>
 /// <param name="people"></param>
 /// <param name="previousResults"></param>
 /// <returns></returns>
 public CandiateRanking[] RunStep(Person[] people, CandiateRanking[][] previousResults)
 {
     var summedWeights = from p in people
                         from ranking in p.FullRanking()
                         group ranking.ranking by ranking.candidate into candidateRankings
                         select new CandiateRanking()
                         {
                             candidate = candidateRankings.Key,
                             ranking = candidateRankings.Sum()
                         };
     return summedWeights.ToArray();
 }
        public void TestSimpleRunNoOneFailWhen()
        {
            var people = new Person[] {
                new Person(0, 1, 2),
                new Person(0, 1, 2),
                new Person(0, 1, 2),
                new Person(0, 1, 2),
            };
            var old = new CandiateRanking[][] { new CandiateRanking[] { new CandiateRanking(0, 2), new CandiateRanking(1, 2) } };

            var s = new ESKeepThoseBetterThan(0.7) { DoNothingIfNoOnePasses=false };
            var r = s.RunStep(people, old);
            Assert.AreEqual(0, r.Length, "# of candidates ranked");
        }
        public void TestSimpleRun()
        {
            var people = new Person[] {
                new Person(0, 1, 2),
                new Person(0, 1, 2),
                new Person(0, 1, 2),
                new Person(0, 1, 2),
            };
            var old = new CandiateRanking[][] { new CandiateRanking[] { new CandiateRanking(0, 3), new CandiateRanking(1, 1) } };

            var s = new ESKeepThoseBetterThan(0.7);
            var r = s.RunStep(people, old);
            Assert.AreEqual(1, r.Length, "# of candidates ranked");
            Assert.AreEqual(0, r[0].candidate, "Incorrect candidate came back");
        }
        /// <summary>
        /// Calculate weights for all candidates by the #1 choice out there.
        /// </summary>
        /// <param name="people"></param>
        /// <returns></returns>
        public CandiateRanking[] RunStep(Person[] people, CandiateRanking[][] previousResults)
        {
            // Weights only work for the best candidate.
            var bestvote = from p in people
                             let ranking = p.FullRanking()
                             let bestRanking = from r in ranking
                                               orderby r.ranking descending
                                               select r
                             select bestRanking.First().candidate;

            // Group them by their best vote and tally them up!
            return (from bc in bestvote
                   group bc by bc into candidatecounts
                   select new CandiateRanking (candidatecounts.Key, candidatecounts.Count())).ToArray();
        }
        /// <summary>
        /// Run an election on a given set of people. Return the full candidate ordering
        /// when we are done.
        /// </summary>
        /// <param name="people"></param>
        /// <returns>Weights for everyone that got votes, ordered from winner on down</returns>
        private Task<CandiateRanking[]> RunSingleElectionInternal(Person[] people)
        {
            // Quick checks.
            if (_steps.Count == 0)
                throw new InvalidOperationException("Election has no steps defined");
            if (people == null || people.Length == 0)
                throw new ArgumentException("Election can't happen without people");

            return Task<CandiateRanking[]>.Factory.StartNew(() =>
                {
                    List<CandiateRanking[]> results = new List<CandiateRanking[]>();
                    int[] keepOnly = new int[0];
                    int oldKeepCount = 0;
                    var peopleThisRound = people;
                    foreach (var s in _steps)
                    {
                        // First, window out people if we need to.
                        if (keepOnly.Length != oldKeepCount)
                        {
                            var keepThem = keepOnly.ToArray();
                            peopleThisRound = peopleThisRound.Select(p => p.KeepCandidates(keepThem)).ToArray();
                            oldKeepCount = keepOnly.Length;
                        }

                        // Run the election
                        var stepResult = s.RunStep(peopleThisRound, results.ToArray());

                        // Some simple case results that will terminate our processing of the election.
                        if (stepResult == null)
                            throw new InvalidOperationException("Election step returned a null value!");
                        if (stepResult.Length == 0)
                            throw new ElectionFailureException("Election step returned zero candidates");
                        if (stepResult.Length == 1)
                            return stepResult;

                        // Save the results for use in future steps.
                        results.Add(stepResult);

                        // And only let through the candidates that made it.
                        keepOnly = stepResult.Select(c => c.candidate).ToArray();
                    }

                    return (from fr in results.Last()
                            orderby fr.ranking descending
                            select fr).ToArray();
                });
        }
        public void Test3PersonElection()
        {
            var people = new Person[] {
                new Person(2, 1, 0), new Person(1, 0, 2), new Person(0, 1, 2)
            };

            var es = new ESBorda();
            var result = es.RunStep(people, null).OrderBy(g => g.ranking).ToArray();

            Assert.AreEqual(3, result.Length, "Result length");
            var ranking1 = result[0];

            var ranking2 = result[1];
            var ranking3 = result[2];
            Assert.AreEqual(1, ranking3.candidate, "candidate 1 index");
            Assert.AreEqual(4, ranking3.ranking, "candidate 1 ranking");
        }
        /// <summary>
        /// Window out the list of candidates.
        /// </summary>
        /// <param name="people"></param>
        /// <param name="previousResults"></param>
        /// <returns></returns>
        public CandiateRanking[] RunStep(Person[] people, CandiateRanking[][] previousResults)
        {
            if (previousResults == null || previousResults.Length == 0)
                throw new ArgumentException("Cant run the elections step that keeps the best guys if we don't have the result of an election!");

            var lastStepResults = previousResults[previousResults.Length-1];
            var passed = (from c in lastStepResults
                          where ((double)c.ranking) / ((double)people.Length) > MinimumFraction
                          select c).ToArray();

            if (passed.Length == 0)
            {
                if (DoNothingIfNoOnePasses)
                    return lastStepResults;
                return new CandiateRanking[] { };
            }

            return passed;
        }
 public void TestKeepOnlyCandidatesOne()
 {
     var p = new Person(0, 1, 2, 3);
     var p1 = p.KeepCandidates(1);
     Assert.AreEqual(1, p1.NumberOfCandidates, "# of candidates when keeping 1");
     Assert.AreEqual(1, p1.FullRanking().First().candidate, "#candidate # 1");
     Assert.AreEqual(0, p1.FullRanking().First().ranking, "Candidate #1 ranking");
 }
 public void TestCreation()
 {
     var p = new Person(5, new Random());
     Assert.AreEqual(5, p.NumberOfCandidates, "# of candidates");
 }
 public void TestRankingOK()
 {
     int count = 10;
     var p = new Person(count, new Random());
     var seen = new SortedSet<int>();
     foreach (var candidate in Enumerable.Range(0, 10))
     {
         var r = p.Ranking(candidate);
         Assert.IsFalse(seen.Contains(r), "Duplicate ranking");
         seen.Add(r);
         Console.WriteLine("Candiate {0} has rank {1}.", candidate, r);
     }
     Assert.AreEqual(count, seen.Count, "Size of the count");
 }
        public void TestKeepOnlyCandidatestwo()
        {
            var p = new Person(3, 2, 1, 0);
            var pn = p.KeepCandidates(3, 1);
            Assert.AreEqual(2, pn.NumberOfCandidates, "# of candidates when keeping 1");
            var p3 = pn.FullRanking().Where(c => c.candidate == 3).FirstOrDefault();
            var p1 = pn.FullRanking().Where(c => c.candidate == 1).FirstOrDefault();

            Assert.IsNotNull(p3, "Candidate 3");
            Assert.IsNotNull(p1, "Candidate 1");

            Assert.AreEqual(0, p1.ranking, "Candidate 1 ranking");
            Assert.AreEqual(1, p3.ranking, "Candidate 3 ranking");
        }
        /// <summary>
        /// Generate the people we want.
        /// </summary>
        /// <returns></returns>
        private IEnumerable<Person> GeneratePeople()
        {
            var r = new Random();
            bool satisfiedAllConstraints = _constraints.Count == 0;
            int constraintIndex = 0;
            int counter = 0;
            int thisConstraintSatisifedEvents = 0;

            var constraints = (from c in _constraints
                               orderby c.fraction ascending
                               select c).ToArray();

            List<Person> alreadyGood = new List<Person>();

            while (counter < NumberOfPeople)
            {
                var p = new Person(NumberOfCandidates, r);
                if (!satisfiedAllConstraints)
                {
                        if (constraints.Take(constraintIndex).Where(c => c.constraint(p)).Any())
                            continue;
                        if (!constraints[constraintIndex].constraint(p))
                            continue;
                        thisConstraintSatisifedEvents++;
                        if (thisConstraintSatisifedEvents >= (constraints[constraintIndex].fraction * NumberOfPeople))
                        {
                            constraintIndex++;
                            if (constraintIndex < constraints.Length)
                            {
                                thisConstraintSatisifedEvents = alreadyGood.Where(lp => constraints[constraintIndex].constraint(lp)).Count();
                            }
                            else
                            {
                                satisfiedAllConstraints = true;
                            }
                        }
                }
                else
                {
                    if (constraints.Where(c => c.constraint(p)).Any())
                        continue;
                }

                alreadyGood.Add(p);
                yield return p;
                counter++;
            }

            if (!satisfiedAllConstraints)
            {
                throw new InvalidOperationException("People constraints may be incompatible - unable to satisfy them this time around!");
            }
        }
 public void TestRankingOutOfBounds()
 {
     int count = 10;
     var p = new Person(count, new Random());
     var r = p.Ranking(count + 1);
 }
 public void TestRemoveCandidates1RemovedCandidateReference()
 {
     var p = new Person(2, 1, 0);
     var p1 = p.RemoveCandidates(1);
     p1.Ranking(1);
 }
        private static void TestFullRankingWithOneGoneParameterized(Person p)
        {
            var fr = p.FullRanking(new int[] { 1 }).ToArray();
            Assert.AreEqual(2, fr.Length, "Incorrect number came back");
            CheckContiguous(fr.Select(c => c.ranking).ToArray(), 2);
            var s = new SortedSet<int>(fr.Select(c => c.candidate));
            Assert.IsFalse(s.Contains(1), "candidate 1 should not be in there");

            var fullOrdering = (from c in p.FullRanking()
                                orderby c.ranking ascending
                                select c).ToArray();
            var partialOrdering = (from c in fr
                                   orderby c.ranking ascending
                                   select c).ToArray();

            int i_p = 0;
            for (int i_f = 0; i_f < fullOrdering.Length; i_f++)
            {
                if (fullOrdering[i_f].candidate != 1)
                {
                    if (fullOrdering[i_f].candidate == partialOrdering[i_p].candidate)
                    {
                        i_p++;
                    }
                }
            }
            Assert.AreEqual(partialOrdering.Length, i_p, "Partial list not ordered correctly");
        }
 public void TestExplicitCreation3BadMissing()
 {
     var p = new Person(2, 0);
 }
 public void TestExplicitCreate1Bad()
 {
     var p = new Person(0);
     p.Ranking(1);
 }
 public void TestExplicitCreation3BadDuplicate()
 {
     var p = new Person(2, 0, 2);
 }
 public void TestRemoveCandidates1Twice()
 {
     var p = new Person(2, 1, 0);
     var p1 = p.RemoveCandidates(1);
     var p2 = p.RemoveCandidates(1);
     Assert.AreEqual(2, p2.NumberOfCandidates, "# of candidates after 1 removed twice");
 }
        public void TestFullRankingWithOneGone2()
        {
            var p = new Person(2, 1, 0);
            Assert.AreEqual(0, p.Ranking(0), "Rank for 0");
            Assert.AreEqual(2, p.Ranking(2), "Rank for 0");
            var ranking = p.FullRanking(1).ToArray();
            Assert.AreEqual(2, ranking.Length, "# of ranked outputs");

            var c0 = ranking.Where(c => c.candidate == 0).First().ranking;
            var c2 = ranking.Where(c => c.candidate == 2).First().ranking;

            Assert.AreEqual(0, c0, "Ranking for candidate 0");
            Assert.AreEqual(1, c2, "Ranking for candidate 2");
        }
 public void TestFullRankingWithTwoGone()
 {
     var p = new Person(3, new Random());
     var fr = p.FullRanking(new int[] { 1, 0 }).ToArray();
     Assert.AreEqual(1, fr.Length, "Incorrect number came back");
     CheckContiguous(fr.Select(c => c.ranking).ToArray(), 1);
     var s = new SortedSet<int>(fr.Select(c => c.candidate));
     Assert.IsFalse(s.Contains(1), "candidate 1 should not be in there");
     Assert.IsFalse(s.Contains(3), "candidate 3 should not be in there");
 }
 public void TestRemoveCandidates1()
 {
     var p = new Person(2, 1, 0);
     var p1 = p.RemoveCandidates(1);
     Assert.AreEqual(0, p1.Ranking(0), "Ranking of zero");
     Assert.AreEqual(1, p1.Ranking(2), "Ranking of candidate #2");
     Assert.AreEqual(2, p1.FullRanking().Count(), "# of candidates around now");
     Assert.AreEqual(2, p1.NumberOfCandidates, "# of candidates stored");
 }
 public void TestFullRanking()
 {
     var p = new Person(3, new Random());
     var fr = p.FullRanking().ToArray();
     CheckContiguous(fr.Select(c => c.ranking).ToArray(), 3);
     CheckContiguous(fr.Select(c => c.candidate).ToArray(), 3);
 }
 public void TestRemoveCandidates2()
 {
     var p = new Person(2, 1, 0);
     var p1 = p.RemoveCandidates(1, 0);
     Assert.AreEqual(0, p1.Ranking(2), "Ranking of candidate #2");
     Assert.AreEqual(1, p1.FullRanking().Count(), "# of candidates around now");
 }