public void Optimise() { var groupSize = Size(); var optimisedGroup = new PermutationGroup(Generators[0]); var optimisedGroupSize = optimisedGroup.Size(); var generatorIndex = 0; do { var copiedOptimised = new PermutationGroup(optimisedGroup.Generators); copiedOptimised.AddGenerator(Generators[generatorIndex]); if (copiedOptimised.Size() > optimisedGroupSize) { optimisedGroup.AddGenerator(Generators[generatorIndex]); optimisedGroupSize = optimisedGroup.Size(); } generatorIndex = (generatorIndex + 1) % Generators.Count; } while (optimisedGroupSize < groupSize); Generators.Clear(); InverseGenerators.Clear(); foreach (var generator in optimisedGroup.Generators) { AddGenerator(generator); } }
public HashSet <Points> OrbitStabiliser(Points partialPoints, out PermutationGroup stabiliser) { stabiliser = new PermutationGroup(); var elementLookup = new Dictionary <Points, Element>(); var orbitPoints = new HashSet <Points>(new[] { partialPoints }); var queue = new Queue <Points>(orbitPoints); elementLookup[partialPoints] = Identity; while (queue.Any()) { var headPoints = queue.Dequeue(); for (var i = 0; i < Generators.Count; ++i) { var permutedPoints = Apply(i, headPoints); if (orbitPoints.Contains(permutedPoints)) { stabiliser.AddGenerator((elementLookup[headPoints].Apply(Generators[i])).Apply(elementLookup[permutedPoints].Inverse())); continue; } orbitPoints.Add(permutedPoints); queue.Enqueue(permutedPoints); elementLookup[permutedPoints] = elementLookup[headPoints].Apply(Generators[i]); } } return(orbitPoints); }