// Assume:
        // (a) The entire bloc needs to use the same strategy, and
        // (b) will never use a strategy that leaves them open to a *worse* outcome, and
        // (c) will only use a non-honest strategy with *some* possibility of a better outcome.
        public override (List <string> Favorite, List <string> Utility) GetPlausibleStrategies()
        {
            var possibleOutcomesByFavoriteStrategy = m_possibleBallots.Length.LengthArray(_ => new Dictionary <PermutationGroup, double[]>());
            var possibleOutcomesByUtilityStrategy  = m_possibleBallots.Length.LengthArray(_ => new Dictionary <PermutationGroup, double[]>());

            foreach (var permuation in GetAllPermutations(m_possibleBallots.Length.LengthArray(i => m_possibleBallots[i].Length)))
            {
                var utilities = GetUtility(permuation);

                for (int i = 0; i < m_possibleBallots.Length; i++)
                {
                    var key = new PermutationGroup(i, permuation);

                    if (!possibleOutcomesByFavoriteStrategy[i].TryGetValue(key, out var favoriteOutcomes))
                    {
                        possibleOutcomesByFavoriteStrategy[i][key] = favoriteOutcomes = new double[m_possibleBallots[i].Length];
                    }

                    if (!possibleOutcomesByUtilityStrategy[i].TryGetValue(key, out var utilityOutcomes))
                    {
                        possibleOutcomesByUtilityStrategy[i][key] = utilityOutcomes = new double[m_possibleBallots[i].Length];
                    }

                    favoriteOutcomes[permuation[i]] = utilities.Favorite[i];
                    utilityOutcomes[permuation[i]]  = utilities.Utility[i];
                }
            }

            return(GetPlausibleStrategies(possibleOutcomesByFavoriteStrategy), GetPlausibleStrategies(possibleOutcomesByUtilityStrategy));
        }
Example #2
0
        public void OptimisedStabiliser()
        {
            //	This group is a 3x3 grid with symmetric rows and columns
            var group = new PermutationGroup(
                new Cycle(new [] { 0, 1 }, new [] { 3, 4 }, new [] { 6, 7 }),
                new Cycle(new [] { 0, 1, 2 }, new [] { 3, 4, 5 }, new [] { 6, 7, 8 }),
                new Cycle(new [] { 0, 3 }, new [] { 1, 4 }, new [] { 2, 5 }),
                new Cycle(new [] { 0, 3, 6 }, new [] { 1, 4, 7 }, new [] { 2, 5, 8 })
                );

            PermutationGroup stabilisedPointZero;

            group.OrbitStabiliser(new Points(0), out stabilisedPointZero);

            stabilisedPointZero.Optimise();

            Assert.AreEqual(2, stabilisedPointZero.GeneratorCount);

            var orbitOfZeroOnStabiliserZero = stabilisedPointZero.Orbit(0);
            var orbitOfOneOnStabiliserZero  = stabilisedPointZero.Orbit(1);
            var orbitOfFourOnStabiliserZero = stabilisedPointZero.Orbit(4);

            CollectionAssert.AreEquivalent(new [] { new [] { 0 } }, orbitOfZeroOnStabiliserZero);
            CollectionAssert.AreEquivalent(new [] { new [] { 1 }, new [] { 2 } }, orbitOfOneOnStabiliserZero);
            CollectionAssert.AreEquivalent(new [] { new [] { 4 }, new [] { 5 }, new [] { 7 }, new [] { 8 } }, orbitOfFourOnStabiliserZero);
        }
Example #3
0
        public void ImageTest()
        {
            var group = new PermutationGroup(new Cycle(new [] { 0, 1 }, new [] { 2, 3 }, new [] { 4, 5 }, new [] { 6, 7 }, new [] { 8, 9 }));

            CollectionAssert.AreEqual(new Image <string>(new [] { "B", "A", "D", "C", "F", "E", "H", "G", "J", "I" }),
                                      group.Apply(0, new Image <string>(new [] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" })));
        }
        private void Setup(IAtomContainer atomContainer)
        {
            // have to setup the connection table before making the group
            // otherwise the size may be wrong, but only setup if it doesn't exist
            IRefinable refinable = GetRefinable(atomContainer);

            int size = GetVertexCount();
            PermutationGroup group = new PermutationGroup(new Permutation(size));

            base.Setup(group, new EquitablePartitionRefiner(refinable));
        }
Example #5
0
        public void OrbitStabiliser()
        {
            //	This group is a 3x3 grid with symmetric rows and columns
            var group = new PermutationGroup(
                new Cycle(new [] { 0, 1 }, new [] { 3, 4 }, new [] { 6, 7 }),
                new Cycle(new [] { 0, 1, 2 }, new [] { 3, 4, 5 }, new [] { 6, 7, 8 }),
                new Cycle(new [] { 0, 3 }, new [] { 1, 4 }, new [] { 2, 5 }),
                new Cycle(new [] { 0, 3, 6 }, new [] { 1, 4, 7 }, new [] { 2, 5, 8 })
                );

            PermutationGroup stabilisedPointZero;
            var orbitZero = group.OrbitStabiliser(new Points(0), out stabilisedPointZero);

            CollectionAssert.AreEquivalent(Enumerable.Range(0, 9).Select(i => new [] { i }), orbitZero);

            var orbitOfZeroOnStabiliserZero = stabilisedPointZero.Orbit(0);
            var orbitOfOneOnStabiliserZero  = stabilisedPointZero.Orbit(1);
            var orbitOfFourOnStabiliserZero = stabilisedPointZero.Orbit(4);

            CollectionAssert.AreEquivalent(new [] { new [] { 0 } }, orbitOfZeroOnStabiliserZero);
            CollectionAssert.AreEquivalent(new [] { new [] { 1 }, new [] { 2 } }, orbitOfOneOnStabiliserZero);
            CollectionAssert.AreEquivalent(new [] { new [] { 4 }, new [] { 5 }, new [] { 7 }, new [] { 8 } }, orbitOfFourOnStabiliserZero);
        }
Example #6
0
        public void CycleTest()
        {
            var group = new PermutationGroup(new Cycle(new [] { 0, 1 }, new [] { 2, 3 }, new [] { 4, 5 }, new [] { 6, 7 }, new [] { 8, 9 }));

            CollectionAssert.AreEqual(new [] { 1, 0, 3, 2, 5, 4, 7, 6, 9, 8 }, group.Apply(0, new Points(new [] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 })));
        }
Example #7
0
        public void PointsTest()
        {
            var group = new PermutationGroup(new Cycle(new [] { 0, 1 }, new [] { 2, 3 }, new [] { 4, 5 }, new [] { 6, 7 }, new [] { 8, 9 }));

            CollectionAssert.AreEqual(new Points(new [] { 2, 4, 3 }), group.Apply(0, new Points(new [] { 3, 5, 2 })));
        }
 /// <summary>
 /// Speed up the search for the automorphism group using the automorphisms in
 /// the supplied group. Note that the behaviour of this method is unknown if
 /// the group does not contain automorphisms...
 /// </summary>
 /// <param name="atomContainer">the atom container to use</param>
 /// <param name="group">the group of known automorphisms</param>
 /// <returns>the full automorphism group</returns>
 public PermutationGroup GetAutomorphismGroup(IAtomContainer atomContainer, PermutationGroup group)
 {
     Setup(atomContainer, group);
     base.Refine(refinable.GetInitialPartition());
     return(base.GetAutomorphismGroup());
 }
 private void Setup(IAtomContainer atomContainer, PermutationGroup group)
 {
     base.Setup(group, new EquitablePartitionRefiner(GetRefinable(atomContainer)));
 }
        private List <string> GetPlausibleStrategies(Dictionary <PermutationGroup, double[]>[] possibleOutcomesByStrategy)
        {
            var plausibleStrategies = m_possibleBallots
                                      .SelectToArray(p => Enumerable.Range(0, p.Length).ToHashSet());

            bool TrimPossibleStrategies(Func <IEnumerable <double[]>, int[], IEnumerable <int>, IEnumerable <int> > getDominatedStrategies)
            {
                bool removedAny = false;

                for (int i = 0; i < m_possibleBallots.Length; i++)
                {
                    if (m_possibleBallots[i].Length == 1)
                    {
                        continue;
                    }

                    foreach (var s in getDominatedStrategies(possibleOutcomesByStrategy[i].Values, m_strategyTiebreakers[i], plausibleStrategies[i]).ToList())
                    {
                        removedAny = true;
                        plausibleStrategies[i].Remove(s);
                    }
                }

                if (removedAny)
                {
                    if (plausibleStrategies.Any(ps => ps.Count == 0))
                    {
                        throw new InvalidOperationException("There's a bug!");
                    }

                    for (int i = 0; i < m_possibleBallots.Length; i++)
                    {
                        foreach (var key in possibleOutcomesByStrategy[i].Keys.Where(pg => !pg.IsStillValid(plausibleStrategies)).ToList())
                        {
                            possibleOutcomesByStrategy[i].Remove(key);
                        }
                    }
                }

                return(removedAny);
            }

            // Eliminate all strategies which bring no benefit to their employer over a more-preferred strategy
            // Ignore any strategies which are strictly dominated by another.
            while (TrimPossibleStrategies((outcomes, tiebreakers, strategies) =>
                                          from a in strategies
                                          from b in strategies
                                          where a != b &&
                                          outcomes.All(outcome => outcome[b] >= outcome[a]) &&
                                          (tiebreakers[b] < tiebreakers[a] ||
                                           outcomes.Any(outcome => outcome[b] != outcome[a]))
                                          select a))
            {
                ;
            }

            // Finally, return all strategies which are part of Nash equilibiria
            // (where no voter can unilaterally improve the outcome)
            var plausibleStrategyNames      = new HashSet <string>();
            var plausibleStrategyLists      = plausibleStrategies.SelectToArray(a => a.ToList());
            var votersWithMutipleStrategies = Enumerable.Range(0, m_voterCount).Where(i => plausibleStrategies[i].Count > 1).ToList();

            foreach (var strategyPermutation in GetAllPermutations(m_voterCount.LengthArray(i => plausibleStrategies[i].Count)))
            {
                var ballotPermutation = m_voterCount.LengthArray(i => plausibleStrategyLists[i][strategyPermutation[i]]);

                var isNashEquilibria = votersWithMutipleStrategies.All(i =>
                {
                    var key = new PermutationGroup(i, ballotPermutation);

                    var outcomes           = possibleOutcomesByStrategy[i][key];
                    var permutationOutcome = outcomes[ballotPermutation[i]];

                    return(!plausibleStrategyLists[i].Any(o => outcomes[o] > permutationOutcome));
                });

                if (isNashEquilibria)
                {
                    for (int i = 0; i < m_voterCount; i++)
                    {
                        if (ballotPermutation[i] > 0)
                        {
                            plausibleStrategyNames.Add(m_strategyNames[i][ballotPermutation[i]]);
                        }
                    }
                }
            }

            return(plausibleStrategyNames.ToList());
        }