/// <summary> /// Create a pruning table using corner permutation and equator order. /// Every table entry contains the exact number of moves required to /// solve the position represented by said coordinates. /// </summary> /// <returns> /// Create a pruning table using corner permutation equator order. /// </returns> public static byte[] CreatePhase2CornerEquatorTable() { byte invalid = 255; byte[] pruningTable = Enumerable .Repeat(invalid, PruningTableConstants.CornerEquatorPruningTableSizePhase2) .ToArray(); TableController.InitializeCornerPermutationMoveTable(); TableController.InitializeEquatorOrderMoveTable(); pruningTable[0] = 0; //solved int done = 1; int depth = 0; string outputFormat = "depth: {0}, done: {1}/" + PruningTableConstants.CornerEquatorPruningTableSizePhase2 + " ({2:P})"; Console.WriteLine(string.Format(outputFormat, depth, done, done / (double)PruningTableConstants.CornerEquatorPruningTableSizePhase2)); while (done < PruningTableConstants.CornerEquatorPruningTableSizePhase2) { for (int cornerPermutation = 0; cornerPermutation < NumCornerPermutations; cornerPermutation++) { for (int equatorPermutation = 0; equatorPermutation < NumEquatorOrders; equatorPermutation++) { int index = NumEquatorOrders * cornerPermutation + equatorPermutation; if (pruningTable[index] == depth) { foreach (int move in TwoPhaseConstants.Phase2Moves) { int newCornerPermutation = TableController.CornerPermutationMoveTable[cornerPermutation, move]; int newEquatorOrder = TableController.EquatorOrderMoveTable[equatorPermutation, move]; int newIndex = NumEquatorOrders * newCornerPermutation + newEquatorOrder; if (pruningTable[newIndex] == invalid) { pruningTable[newIndex] = (byte)(depth + 1); done++; } } } } } depth++; Console.WriteLine(string.Format(outputFormat, depth, done, done / (double)PruningTableConstants.CornerEquatorPruningTableSizePhase2)); } return(pruningTable); }
//Not used /// <summary> /// Create a weighted pruning table using U- and D-edge order and /// equator edge order. Every table entry contains the minimum cost /// required to solve the position represented by said coordinates. /// </summary> /// <param name="weights">The weights to use.</param> /// <returns> /// A weighted pruning table using U- and D-edge order and equator edge /// order. /// </returns> /// <exception cref="InvalidWeightsException"> /// Thrown if <paramref name="weights"/> is invalid. /// </exception> public static float[] CreateWeightedPhase2UdEquatorTable(float[] weights) { MoveWeightsUtils.ValidateWeights(weights); float invalid = float.NaN; float[] pruningTable = Enumerable .Repeat(invalid, PruningTableConstants.UdEquatorPruningTableSizePhase2) .ToArray(); TableController.InitializeUdEdgeOrderMoveTable(); TableController.InitializeEquatorOrderMoveTable(); pruningTable[0] = 0f; int numChanged = -1; while (numChanged != 0) { numChanged = 0; for (int udEdgeOrder = 0; udEdgeOrder < NumUdEdgeOrders; udEdgeOrder++) { for (int equatorOrder = 0; equatorOrder < NumEquatorOrders; equatorOrder++) { int index = NumEquatorOrders * udEdgeOrder + equatorOrder; if (pruningTable[index] != invalid) { foreach (int move in TwoPhaseConstants.Phase2Moves) { int newUdEdgeOrder = TableController.UdEdgeOrderMoveTable[udEdgeOrder, MoveTables.Phase1IndexToPhase2Index[move]]; int newEquatorOrder = TableController.EquatorOrderMoveTable[equatorOrder, move]; int newIndex = NumEquatorOrders * newUdEdgeOrder + newEquatorOrder; float newPruningValue = pruningTable[index] + weights[move]; if (pruningTable[newIndex] == invalid || pruningTable[newIndex] > newPruningValue) { pruningTable[newIndex] = newPruningValue; numChanged++; } } } } } } return(pruningTable); }