lojix/search/src/main/com/thesett/aima/search/impl/IterativeBoundAlgorithm.java
public SearchNode search(QueueSearchState<O, T> initSearch, Collection<T> startStates, int maxSteps,
        int searchSteps) throws SearchNotExhaustiveException
    {
        // Iteratively increase the bound until a search succeeds.
        for (float bound = startBound;;)
        {
            // Set up the maximum bound for this iteration.
            maxBound = bound;

            // Use a try block as the depth bounded search will throw a MaxBoundException if it fails but there
            // are successors states known to exist beyond the current max depth fringe.
            try
            {
                // Get the number of search steps taken so far and pass this into the underlying depth bounded search
                // so that the step count limit carries over between successive iterations.
                int numStepsSoFar = initSearch.getStepsTaken();

                // Call the super class search method to perform a depth bounded search on this maximum bound starting
                // from the initial search state.
                initSearch.resetEnqueuedOnceFlag();

                SearchNode node = super.search(initSearch, startStates, maxSteps, numStepsSoFar);

                // Check if the current depth found a goal node
                if (node != null)
                {
                    return node;
                }

                // The depth bounded search returned null, so it has exhausted the search space. Return with null.
                else
                {
                    return null;
                }
            }

            // The depth bounded search failed but it knows that there are more successor states at deeper levels.
            catch (MaxBoundException e)
            {
                // Do nothing, no node found at this depth so continue at the next depth level
                e = null;
            }

            // Check if the bound should be increased by epsilon or to the next smallest bound property value
            // beyond the fringe and update the bound for the next iteration.
            if (useEpsilon)
            {
                bound = bound + epsilon;
            }
            else
            {
                bound = getMinBeyondBound();
            }
        }
    }
public SearchNode search(QueueSearchState<O, T> initSearch, Collection<T> startStates, int maxSteps,
        int searchSteps) throws SearchNotExhaustiveException
    {
        // Iteratively increase the bound until a search succeeds.
        for (float bound = startBound;;)
        {
            // Set up the maximum bound for this iteration.
            maxBound = bound;

            // Use a try block as the depth bounded search will throw a MaxBoundException if it fails but there
            // are successors states known to exist beyond the current max depth fringe.
            try
            {
                // Get the number of search steps taken so far and pass this into the underlying depth bounded search
                // so that the step count limit carries over between successive iterations.
                int numStepsSoFar = initSearch.getStepsTaken();

                // Call the super class search method to perform a depth bounded search on this maximum bound starting
                // from the initial search state.
                initSearch.resetEnqueuedOnceFlag();

                SearchNode node = super.search(initSearch, startStates, maxSteps, numStepsSoFar);

                // Check if the current depth found a goal node
                if (node != null)
                {
                    return node;
                }

                // The depth bounded search returned null, so it has exhausted the search space. Return with null.
                else
                {
                    return null;
                }
            }

            // The depth bounded search failed but it knows that there are more successor states at deeper levels.
            catch (MaxBoundException e)
            {
                // Do nothing, no node found at this depth so continue at the next depth level
                e = null;
            }

            // Check if the bound should be increased by epsilon or to the next smallest bound property value
            // beyond the fringe and update the bound for the next iteration.
            if (useEpsilon)
            {
                bound = bound + epsilon;
            }
            else
            {
                bound = getMinBeyondBound();
            }
        }
    }
Search iteratively on increasing maximum bound limits until the search space is exhausted or a goal state is
found.

@param  initSearch  The algorithm to turn the start states into the intial set of search nodes, of the correct
type to begin the search with.
@param  startStates The set of start states to begin the search with.
@param  maxSteps    The maximum number of steps to search for before giving up. If this is 0 or less then no
maximum number is enforced.
@param  searchSteps The number of steps taken so far. This may be greater than 0 if this search is run
iteratively and previous iterations of it have already been run.

@return The first {@link SearchNode} corresponding to a goal state that is found or null if none can be found
after exhaustive searching.

@throws SearchNotExhaustiveException SearchNotExhaustiveException If the search terminates prematurely because
the maximum number of steps is reached.