public static void VerifyGroupActionAssociaty() { for (int caseIdx = 0; caseIdx < 100; caseIdx++) { CubeAction a = CubeAction.Random(Utils.GlobalRandom.Next(1, 20)); CubeAction b = CubeAction.Random(Utils.GlobalRandom.Next(1, 15)); CubeAction c = CubeAction.Random(Utils.GlobalRandom.Next(1, 10)); CubeAction ab = a.Mul(b); CubeAction bc = b.Mul(c); CubeState origState = CubeAction.RandomCube(Utils.GlobalRandom.Next(1, 20)); CubeState a_b_c_state = new CubeState(origState); c.Act(a_b_c_state); b.Act(a_b_c_state); a.Act(a_b_c_state); CubeState ab_c_state = new CubeState(origState); c.Act(ab_c_state); ab.Act(ab_c_state); CubeState a_bc_state = new CubeState(origState); bc.Act(a_bc_state); a.Act(a_bc_state); Utils.DebugAssert(a_b_c_state.Equals(ab_c_state)); Utils.DebugAssert(a_b_c_state.Equals(a_bc_state)); } }
public static void VerifyOpCountForAccelerationMap() { CubeState state = new CubeState(); CubeAction actionNoAcc = CubeAction.Random(CubeAction.OpCountForAccelerationMap - 1); CubeAction actionAcc = CubeAction.Random(CubeAction.OpCountForAccelerationMap); Console.WriteLine( "Expecting timeNoAcc is similar to timeAcc, " + "otherwise adjust CubeAction.OpCountForAccelerationMap"); for (int i = 0; i < 5; i++) { long timeStart = Utils.CurrentTimeMillis(); for (int j = 0; j < 500; j++) { actionNoAcc.Act(state); } long timeNoAcc = Utils.CurrentTimeMillis(); for (int j = 0; j < 500; j++) { actionAcc.Act(state); } long timeAcc = Utils.CurrentTimeMillis(); Console.WriteLine($"timeNoAcc={timeNoAcc - timeStart}ms, timeAcc={timeAcc - timeNoAcc}ms"); } }
private BlockSet ExploreNewCoset(BlockSet startState, CubeAction generator) { bool foundNew = false; var newState = new BlockSet(startState); generator.Act(newState.State); // To verify generators truely stablizes Stablized BlockSet if (Utils.ShouldVerify()) { foreach (var stablePos in Stablized.Indexes) { if (!newState.State.Blocks[stablePos] .Equals(startState.State.Blocks[stablePos])) { throw new ArgumentException(); } } } if (!OrbitToCoset.ContainsKey(newState)) { foundNew = true; var startCoset = OrbitToCoset[startState]; Utils.DebugAssert(startCoset != null); var newCoset = generator.Mul(startCoset); newCoset.Simplify(CubeAction.SimplifyLevel.Level0); OrbitToCoset.Add(newState, newCoset); } return(foundNew ? newState : null); }
public bool IsStablizedBy(CubeAction action) { var actionCopy = new BlockSet(this); action.Act(actionCopy.State); return(this.Equals(actionCopy)); }
public static void VerifyCubeTurnAround() { for (int caseIdx = 0; caseIdx < 100; caseIdx++) { CubeState cubeState = CubeAction.RandomCube(Utils.GlobalRandom.Next(1, 30)); foreach (CubeOp.Type op in Enum.GetValues(typeof(CubeOp.Type))) { var action = new CubeAction(new int[] { (int)op }); CubeState newCubeState = new CubeState(cubeState); for (int i = 0; i < CubeState.TurnAround; i++) { action.Act(newCubeState); } Utils.DebugAssert(newCubeState.Equals(cubeState)); } } for (int caseIdx = 0; caseIdx < 100; caseIdx++) { CubeState cubeState = CubeAction.RandomCube(Utils.GlobalRandom.Next(1, 30)); foreach (CubeOp.Type op in Enum.GetValues(typeof(CubeOp.Type))) { var action = new CubeAction(new int[] { (int)op, (int)op, (int)op }); CubeState newCubeState = new CubeState(cubeState); for (int i = 0; i < CubeState.TurnAround; i++) { action.Act(newCubeState); } Utils.DebugAssert(newCubeState.Equals(cubeState)); } } for (int caseIdx = 0; caseIdx < 100; caseIdx++) { CubeState cubeState = CubeAction.RandomCube(Utils.GlobalRandom.Next(1, 30)); foreach (CubeOp.Type op in Enum.GetValues(typeof(CubeOp.Type))) { var action = new CubeAction(new int[] { (int)op, (int)op }); CubeState newCubeState = new CubeState(cubeState); for (int i = 0; i < CubeState.TurnAround / 2; i++) { action.Act(newCubeState); } Utils.DebugAssert(newCubeState.Equals(cubeState)); } } }
private CubeAction DetermineBelongingCoset(CubeAction e) { var eState = new BlockSet(ToStablize); e.Act(eState.State); if (!OrbitToCoset.ContainsKey(eState)) { return(null); } var cosetRepresentative = OrbitToCoset[eState]; if (Utils.ShouldVerify()) { { var cosetReprState = new BlockSet(ToStablize); cosetRepresentative.Act(cosetReprState.State); Utils.DebugAssert(cosetReprState.Equals(eState)); } { // States in orbit 1-to-1 maps to each *left* coset (gH). I.e. // iff. e^(-1) * cosetRepresentative stablizes the BlockSet being // observed. This deduces that, group actions in same *left* // coset, always act the BlockSet being observed to the same state. var reCosetRep = e.Reverse().Mul(cosetRepresentative); Utils.DebugAssert(Stablized.IsStablizedBy(reCosetRep)); } { // Iff. e * cosetRepresentative^(-1) stablizes the BlockSet being // observed. This is the condition for *right* coset. It is not what // we need here, and group actions in same *right* coset, may act the // BlockSet being observed to different states. var eRCosetRep = e.Mul(cosetRepresentative.Reverse()); // Utils.DebugAssert(observed.IsStablizedBy(eRCosetRep)); // Doesn't hold } } return(cosetRepresentative); }