int Solver::Solve2(KociembaCube& cube) { int iteration = 1; int result = NOT_FOUND; // Establish initial cost estimate to goal state threshold2 = Phase2Cost( cube.CornerPermutation(), cube.NonMiddleSliceEdgePermutation(), cube.MiddleSliceEdgePermutation()); nodes2 = 1; // Count root node here solutionLength2 = 0; do { newThreshold2 = Huge; // Any cost will be less than this // Perform the phase 2 recursive IDA* search result = Search2( cube.CornerPermutation(), cube.NonMiddleSliceEdgePermutation(), cube.MiddleSliceEdgePermutation(), 0); // Establish a new threshold for a deeper search threshold2 = newThreshold2; // Count interative deepenings iteration++; } while (result == NOT_FOUND); // cout << "Phase 2 nodes = " << nodes2 << endl; return result; }
int Solver::Solve2(KociembaCube& cube) { int iteration = 1; int result = NOT_FOUND; threshold2 = Phase2Cost( cube.CornerPermutation(), cube.NonMiddleSliceEdgePermutation(), cube.MiddleSliceEdgePermutation()); nodes++; nodes2 = 1; solutionLength2 = 0; do { newThreshold2 = Huge; result = Search2( cube.CornerPermutation(), cube.NonMiddleSliceEdgePermutation(), cube.MiddleSliceEdgePermutation(), 0); threshold2 = newThreshold2; iteration++; } while (result == NOT_FOUND); Application->processEvents(); return result; }
int Solver::Search2( int cornerPermutation, int nonMiddleSliceEdgePermutation, int middleSliceEdgePermutation, int depth) { int cost, totalCost; int move; int power, powerLimit; int cornerPermutation2; int nonMiddleSliceEdgePermutation2; int middleSliceEdgePermutation2; int result; // Compute cost estimate to goal state cost = Phase2Cost( cornerPermutation, nonMiddleSliceEdgePermutation, middleSliceEdgePermutation); // h if (cost == 0) // Solution found... { solutionLength2 = depth; // Save phase 2 solution length if (solutionLength1 + solutionLength2 < minSolutionLength) minSolutionLength = solutionLength1 + solutionLength2; PrintSolution(); return FOUND; } // See if node should be expanded totalCost = depth + cost; // g + h if (totalCost <= threshold2) // Expand node { // No point in continuing to search for solutions of equal or greater // length than the current best solution if (solutionLength1 + depth >= minSolutionLength-1) return ABORT; for (move = Cube::Move::R; move <= Cube::Move::B; move++) { if (Disallowed(move, solutionMoves2, depth)) continue; cornerPermutation2 = cornerPermutation; nonMiddleSliceEdgePermutation2 = nonMiddleSliceEdgePermutation; middleSliceEdgePermutation2 = middleSliceEdgePermutation; solutionMoves2[depth] = move; powerLimit = 4; if (move != Cube::Move::U && move != Cube::Move::D) powerLimit=2; for (power = 1; power < powerLimit; power++) { cornerPermutation2 = cornerPermutationMoveTable[cornerPermutation2][move]; nonMiddleSliceEdgePermutation2 = nonMiddleSliceEdgePermutationMoveTable[nonMiddleSliceEdgePermutation2][move]; middleSliceEdgePermutation2 = middleSliceEdgePermutationMoveTable[middleSliceEdgePermutation2][move]; solutionPowers2[depth] = power; nodes2++; // Apply the move if (result = Search2( cornerPermutation2, nonMiddleSliceEdgePermutation2, middleSliceEdgePermutation2, depth+1)) return result; } } } else // Maintain minimum cost exceeding threshold { if (totalCost < newThreshold2) newThreshold2 = totalCost; } return NOT_FOUND; }
int Solver::Search2( int cornerPermutation, int nonMiddleSliceEdgePermutation, int middleSliceEdgePermutation, int depth) { int cost, totalCost; int move; int power, powerLimit; int cornerPermutation2; int nonMiddleSliceEdgePermutation2; int middleSliceEdgePermutation2; int result; cost = Phase2Cost( cornerPermutation, nonMiddleSliceEdgePermutation, middleSliceEdgePermutation); if (cost == 0) { solutionLength2 = depth; if (solutionLength1 + solutionLength2 < minSolutionLength) minSolutionLength = solutionLength1 + solutionLength2; PrintSolution(); return FOUND; } if (cost < 2) Window->ProgressStep(1); totalCost = depth + cost; if (totalCost <= threshold2) { if (solutionLength1 + depth >= minSolutionLength-1) return ABORT; for (move = Cube::R; move <= Cube::B; move++) { if (Disallowed(move, solutionMoves2, depth)) continue; cornerPermutation2 = cornerPermutation; nonMiddleSliceEdgePermutation2 = nonMiddleSliceEdgePermutation; middleSliceEdgePermutation2 = middleSliceEdgePermutation; solutionMoves2[depth] = move; powerLimit = 4; if (move != Cube::U && move != Cube::D) powerLimit=2; for (power = 1; power < powerLimit; power++) { cornerPermutation2 = cornerPermutationMoveTable [cornerPermutation2][move]; nonMiddleSliceEdgePermutation2 = nonMiddleSliceEdgePermutationMoveTable [nonMiddleSliceEdgePermutation2][move]; middleSliceEdgePermutation2 = middleSliceEdgePermutationMoveTable [middleSliceEdgePermutation2][move]; solutionPowers2[depth] = power; nodes2++; if ((result = Search2( cornerPermutation2, nonMiddleSliceEdgePermutation2, middleSliceEdgePermutation2, depth+1))) return result; } } } else { if (totalCost < newThreshold2) newThreshold2 = totalCost; } return NOT_FOUND; }