Exemplo n.º 1
0
int Solver::Solve(KociembaCube& scrambledCube)
{
	int iteration = 1;
	int result = NOT_FOUND;

	// Make a copy of the scrambled cube for use later on
	cube = scrambledCube;

	// Establish initial cost estimate to goal state
	threshold1 = Phase1Cost(cube.Twist(), cube.Flip(), cube.Choice());

	nodes1 = 1;		// Count root node here
	solutionLength1 = 0;

	do
	{
		cout << "threshold(" << iteration
			 << ") = " << threshold1 << endl;

		newThreshold1 = Huge;	// Any cost will be less than this

		// Perform the phase 1 recursive IDA* search
		result = Search1(cube.Twist(), cube.Flip(), cube.Choice(), 0);

		// Establish a new threshold for a deeper search
		threshold1 = newThreshold1;

		// Count interative deepenings
		iteration++;
	} while (result == NOT_FOUND);

	cout << "Phase 1 nodes = " << nodes1 << endl;
	return result;
}
Exemplo n.º 2
0
/*	--- TABEL DENGAN ELEMEN TERURUT MEMBESAR --- */
IdxType SearchUrut (TabInt T, ElType X) {
	/*	Kamus */
	/*	Algoritma */
	if ((IsEmpty(T))||(!SearchB(T,X))) {
		return IdxUndef;
	} else {
		return Search1(T,X);
	}
}
Exemplo n.º 3
0
void Del1Urut (TabInt *T, ElType X) {
	/*	Kamus */
	IdxType i;
	/*	Algoritma */
	if (SearchB(*T,X)) {
		i=Search1(*T,X);
		while (i<GetLastIdx(*T)) {
			SetEl(T,i,GetElmt(*T,i+1));
			i++;
		}
		SetEl(T,i,ValUndef);
	}
}
Exemplo n.º 4
0
int Solver::Solve(KociembaCube& scrambledCube)
{
	int iteration = 1;
	int result = NOT_FOUND;

	stopped = false;
	Window->ProgressInit(0);
	
	cube = scrambledCube;

	threshold1 = Phase1Cost(cube.Twist(), cube.Flip(), cube.Choice());

	nodes = 1;
	solutionLength1 = 0;

	do
	{
		Window->SetInfo("Обработка глубины _%d / %d_",
				iteration, nodes);

		newThreshold1 = Huge;

		result = Search1(cube.Twist(), cube.Flip(), cube.Choice(), 0);

		if(stopped)
		{
			Window->SetInfo("_Готово_");
			return ABORT;
		}

		threshold1 = newThreshold1;
		iteration++;

		Application->processEvents();
	} while (result == NOT_FOUND);

	Window->SetInfo("_Найдено оптимальное решение_");
	return result;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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;

	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;
}