예제 #1
0
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;
}
예제 #2
0
파일: solver.cpp 프로젝트: amine2734/cube
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;
}
예제 #3
0
int Solver::Search1(int twist, int flip, int choice, int depth)
{
	int cost, totalCost;
	int move;
	int power;
	int twist2, flip2, choice2;
	int result;

	// Compute cost estimate to phase 1 goal state
	cost = Phase1Cost(twist, flip, choice);	// h

	if (cost == 0)	// Phase 1 solution found...
	{
		solutionLength1 = depth;	// Save phase 1 solution length

		// We need an appropriately initialized cube in order
		//   to begin phase 2.  First, create a new cube that
		//   is a copy of the initial scrambled cube.  Then we
		//   apply the phase 1 move sequence to that cube.  The
		//   phase 2 search can then determine the initial
		//   phase 2 coordinates (corner, edge, and slice
		//   permutation) from this cube.
		//
		//   Note: No attempt is made to merge moves of the same
		//   face adjacent to the phase 1 & phase 2 boundary since
		//   the shorter sequence will quickly be found.

		KociembaCube phase2Cube = cube;
		for (int i = 0; i < solutionLength1; i++)
		{
			for (power = 0; power < solutionPowers1[i]; power++)
				phase2Cube.ApplyMove(solutionMoves1[i]);
		}
		// Invoke Phase 2
		(void)Solve2(phase2Cube);
	}

	// See if node should be expanded
	totalCost = depth + cost;	// g + h

	if (totalCost <= threshold1)	// Expand node
	{
		// If this happens, we should have found the
		//   optimal solution at this point, so we
		//   can exit indicating such.  Note: the first
		//   complete solution found in phase1 is optimal
		//   due to it being an addmissible IDA* search.
		if (depth >= minSolutionLength-1 || minSolutionLength < 24)
			return OPTIMUM_FOUND;

		for (move = Cube::Move::R; move <= Cube::Move::B; move++)
		{
			if (Disallowed(move, solutionMoves1, depth)) continue;

			twist2  = twist;
			flip2   = flip;
			choice2 = choice;

			solutionMoves1[depth] = move;
			for (power = 1; power < 4; power++)
			{
				solutionPowers1[depth] = power;
				twist2  = twistMoveTable[twist2][move];
				flip2   = flipMoveTable[flip2][move];
				choice2 = choiceMoveTable[choice2][move];
				nodes1++;
				// Apply the move
				if (result = Search1(twist2, flip2, choice2, depth+1))
						return result;
			}
		}
	}
	else	// Maintain minimum cost exceeding threshold
	{
		if (totalCost < newThreshold1)
			newThreshold1 = totalCost;
	}
	return NOT_FOUND;
}
예제 #4
0
파일: solver.cpp 프로젝트: amine2734/cube
int Solver::Search1(int twist, int flip, int choice, int depth)
{
	int cost, totalCost;
	int move;
	int power;
	int twist2, flip2, choice2;
	int result;

	cost = Phase1Cost(twist, flip, choice);

	if (cost == 0)
	{
		solutionLength1 = depth;
		
		KociembaCube phase2Cube = cube;
		for (int i = 0; i < solutionLength1; i++)
		{
			for (power = 0; power < solutionPowers1[i]; power++)
				phase2Cube.ApplyMove(solutionMoves1[i]);
		}

		(void)Solve2(phase2Cube);
		if(stopped) return ABORT;
	}

	totalCost = depth + cost;

	if (totalCost <= threshold1)
	{
		if (depth >= minSolutionLength-1)
			return OPTIMUM_FOUND;
		
		for (move = Cube::R; move <= Cube::B; move++)
		{
			if (Disallowed(move, solutionMoves1, depth)) continue;
				
			twist2  = twist;
			flip2   = flip;
			choice2 = choice;

			solutionMoves1[depth] = move;
			for (power = 1; power < 4; power++)
			{
				solutionPowers1[depth] = power;
				twist2  = twistMoveTable[twist2][move];
				flip2   = flipMoveTable[flip2][move];
				choice2 = choiceMoveTable[choice2][move];

				if ((result =
					Search1(twist2, flip2, choice2, depth+1)))
						return result;
			}
		}
	}
	else
	{
		if (totalCost < newThreshold1)
			newThreshold1 = totalCost;
	}
	return NOT_FOUND;
}