results::WordsVector Searches::advance( std::string query, std::string lang, int size, int offset ) { SearchResults resultIds = SearchEngine::get_instance()->search( query, lang, size, offset ); results::WordsVector wordsVector(resultIds.size()); models::Words wordsModel; int resultSize = resultIds.size(); for (int i = 0; i < resultSize; ++i) { wordsVector[i] = wordsModel.get_word_with_id( resultIds[i] ); } wordsVector.offset = offset; wordsVector.maxsize = resultIds.maxsize; return wordsVector; }
void testSingleSearch() { StarcraftState init(true); //init.doAction(DATA.getAction(BWAPI::UnitTypes::Zerg_Drone), init.resourcesReady(DATA.getAction(BWAPI::UnitTypes::Zerg_Drone))); //init.doAction(DATA.getAction(BWAPI::UnitTypes::Zerg_Drone), init.resourcesReady(DATA.getAction(BWAPI::UnitTypes::Zerg_Drone))); //init.doAction(DATA.getAction(BWAPI::UnitTypes::Zerg_Drone), init.resourcesReady(DATA.getAction(BWAPI::UnitTypes::Zerg_Drone))); //init.doAction(DATA.getAction(BWAPI::UnitTypes::Zerg_Drone), init.resourcesReady(DATA.getAction(BWAPI::UnitTypes::Zerg_Drone))); //init.doAction(DATA.getAction(BWAPI::UnitTypes::Zerg_Spawning_Pool), init.resourcesReady(DATA.getAction(BWAPI::UnitTypes::Zerg_Spawning_Pool))); //init.doAction(DATA.getAction(BWAPI::UnitTypes::Zerg_Extractor), init.resourcesReady(DATA.getAction(BWAPI::UnitTypes::Zerg_Extractor))); init.printData(); SearchParameters params(defaultZergGoal(), init, StarcraftSearchConstraints()); //params.goal.setGoal( DATA.getAction(BWAPI::UnitTypes::Zerg_Zergling), 14); //params.goal.setGoal( DATA.getAction(BWAPI::UnitTypes::Zerg_Drone), 9); params.goal.setGoal( DATA.getAction(BWAPI::UnitTypes::Zerg_Mutalisk), 4); params.goal.setGoalMax( DATA.getAction(BWAPI::UnitTypes::Zerg_Overlord), 3); params.goal.setGoalMax( DATA.getAction(BWAPI::UnitTypes::Zerg_Drone), 12); params.useRepetitions = true; DFBBStarcraftSearch SCSearch(params); SearchResults result = SCSearch.search(); //if (result.solved) //{ result.printResults(true); //} }
static void search_utemplate(br_const_utemplate query, br_callback_context) { SearchResults *searchResults = new FaceRecognition(query); foreach (const MappedGallery &gallery, galleries) br_iterate_utemplates(reinterpret_cast<br_const_utemplate>(gallery.data), reinterpret_cast<br_const_utemplate>(gallery.data + gallery.size), compare_utemplates, searchResults); searchResults->print(); delete searchResults; }
void testSmartSearch() { // default state StarcraftState initialState(true); SmartStarcraftSearch sss; sss.addGoal(DATA.getAction(BWAPI::UnitTypes::Protoss_Carrier), 1); //sss.addGoal(DATA.getAction(BWAPI::UpgradeTypes::Carrier_Capacity), 1); sss.setState(initialState); // do the search SearchResults result = sss.search(); if (result.solved) { result.printResults(true); } }
inline void gatherResultstoProcZero(MPI_Comm comm, SearchResults& boxIdPairResults) { int procId=-1; MPI_Comm_rank(comm, &procId); int numProc=-1; MPI_Comm_size(comm, &numProc); int procIdDestination = 0; stk::CommAll gather(comm); for (int phase=0; phase<2; ++phase) { if ( procId != procIdDestination ) { for (size_t j=0;j<boxIdPairResults.size();++j) { gather.send_buffer(procIdDestination).pack< std::pair<Ident, Ident> >(boxIdPairResults[j]); } } if (phase == 0) { //allocation phase gather.allocate_buffers( numProc / 4 ); } else { // communication phase gather.communicate(); } } if ( procId == procIdDestination ) { for ( int p = 0 ; p < numProc ; ++p ) { stk::CommBuffer &buf = gather.recv_buffer( p ); while ( buf.remaining() ) { std::pair<Ident, Ident> temp; buf.unpack< std::pair<Ident, Ident> >( temp ); boxIdPairResults.push_back(temp); } } } }
yaml::Mapping CyclopsMaster::reduce(const PendingRequest& results) { // for getPoint, we should get errors from all the dataset parts except the one that // actually contained it if (results.request["method"] == "getPoint") { for (int i=0; i<results.replies.size(); i++) { if (results.replies[i].contains("result")) { return results.replies[i]; } } } // for getPoints, we need to get all the datasets we got back (if any), and merge // them together before returning the result. If the total number of points is different // from the number of points we asked, we need to get which are the missing ones and return // an error message with that if (results.request["method"] == "getPoints") { // enclose all of this inside a try/catch block, so that if any error occurs (such as // invalid arguments) we just fall through to the normal reduce/sendReply which will // send the correct error message back to the client // FIXME: this is just a temporary hack, a correct solution would imply a more in-depth // refactoring of how arguments are checked try { if (results.request["params"].sequence().size() < 2) throw InvalidParams(); return reduceGetPoints(results.replies, results.request["params"][1].sequence()); } catch (...) {} /* DataSet resultds; for (int i=0; i<results.replies.size(); i++) { // all replies should contain result, even if only an empty dataset DataSet ds; ds.fromBase64(results.replies[i]["result"].scalar().toAscii()); resultds.appendDataSet(&ds); } if (resultds.size() == results.request["params"][1].sequence().size()) { yaml::Mapping result(results.replies[0]); result["result"] = resultds.toBase64(); return result; } // need to find the missing points QSet<QString> asked; foreach (const yaml::Node& n, results.request["params"][1].sequence()) asked << n.scalar(); QSet<QString> found = QSet<QString>::fromList(resultds.pointNames()); QStringList notfound = (asked - found).toList(); yaml::Mapping result; result.insert("id", results.request["id"]); result.insert("error", QString("Following points could not be found: ") + notfound.join(", ")); return result; */ } // first check there has been no errors, otherwise return that as a common answer for (int i=0; i<results.replies.size(); i++) { if (results.replies[i].contains("error")) { return results.replies[i]; } } // for size queries, we need to sum up the size of all parts if (results.request["method"] == "size") { int total = 0; for (int i=0; i<results.replies.size(); i++) { total += results.replies[i]["result"].scalar().toInt(); } yaml::Mapping result; result.insert("id", results.request["id"]); result.insert("result", QString::number(total)); return result; } // for chainedSearch queries, we need to merge the results now, only keeping the best ones if (results.request["method"] == "chainedSearch") { /* SearchResults allResults; for (int i=0; i<results.replies.size(); i++) { const yaml::Sequence& result = results.replies[i]["result"].sequence(); for (int j=0; j<result.size(); j++) { allResults << Result(result[j][0].scalar(), result[j][1].scalar().toFloat()); } } sort(allResults.begin(), allResults.end(), cmpSearchResults); */ CyclopsResults allResults; for (int i=0; i<results.replies.size(); i++) { const yaml::Sequence& result = results.replies[i]["result"]["results"].sequence(); const yaml::Sequence& values = results.replies[i]["result"]["values"].sequence(); for (int j=0; j<result.size(); j++) { QList<QVariant> vals; int vsize = values[j].sequence().size(); for (int k=0; k<vsize; k++) vals << values[j][k].scalar(); allResults.append(Result(result[j][0].scalar(), result[j][1].scalar().toFloat()), vals); } } allResults.sort(); int nresults = results.request["params"][2].scalar().toInt(); int offset = results.request["params"][3].scalar().toInt(); allResults.mid(offset, qMin(allResults.size()-offset, nresults)); yaml::Mapping result = results.replies[0]; result["result"] = toYaml(allResults); // add the header only now, to avoid a conversion yaml -> QVariant -> yaml result["result"]["header"] = results.replies[0]["result"]["header"]; return result; } // for nnSearch queries, we need to merge the results now, only keeping the best ones if (results.request["method"].scalar().startsWith("nnSearch")) { SearchResults allResults; for (int i=0; i<results.replies.size(); i++) { const yaml::Sequence& result = results.replies[i]["result"].sequence(); for (int j=0; j<result.size(); j++) { allResults << Result(result[j][0].scalar(), result[j][1].scalar().toFloat()); } } sort(allResults.begin(), allResults.end(), cmpSearchResults); int npos = 3; if (results.request["method"].scalar().endsWith("Filter")) npos = 4; int nresults = results.request["params"][npos].scalar().toInt(); allResults = allResults.mid(0, qMin(allResults.size(), nresults)); yaml::Mapping result = results.replies[0]; result["result"] = toYaml(allResults); return result; } // for queries that return None, we can return the first one // for datasetNames, distanceNames and layout, we assume all results are the same and return the first one return results.replies[0]; }
static void compare_utemplates(br_const_utemplate target, br_callback_context context) { SearchResults *searchResults = (SearchResults*) context; searchResults->consider(target); }
void SearchVideos::run() { // search started emit searchStarted(); // stop getting previews imageCatcher->stop(); // clear previous results searchResults->removeAllSearchResults(); // has plugins to search? if (internalPluginsIds.count() == 0) { // search finished emit searchFinished(); // abort process return; } // build the plugins search list QList<VideoInformationPlugin *> plugins; // check which plugins goes into the list if (internalPluginsIds.at(0) == SEARCH_ID_ALL) // all plugins plugins.append(VideoInformation::instance()->getAllSearchPlugins()); else if (internalPluginsIds.at(0) == SEARCH_ID_STANDARD) // all standard plugins plugins.append(VideoInformation::instance()->getAllSearchStandardPlugins()); else if (internalPluginsIds.at(0) == SEARCH_ID_ADULTS) // all adult plugins plugins.append(VideoInformation::instance()->getAllSearchAdultPlugins()); else if (internalPluginsIds.count() == 1) // single search plugins.append(VideoInformation::instance()->getRegisteredPlugin(internalPluginsIds.at(0))); else // custom search, so add them... for (int n = 0; n < internalPluginsIds.count(); n++) plugins.append(VideoInformation::instance()->getRegisteredPlugin(internalPluginsIds.at(n))); // if adult sites are disabled, then remove them from list if (VideoInformation::instance()->getBlockAdultContent()) for (int n = plugins.count() - 1; n >= 0; n--) if (plugins.at(n)->hasAdultContent()) plugins.removeAt(n); // inits int lastCount = 0; // start to search while (!plugins.isEmpty()) { VideoInformationPlugin *plugin = plugins.takeFirst(); if (plugin != NULL) { // execute search into current thread SearchResults results = plugin->searchVideos(internalKeyWords, internalPage); // check if we are destroying the searchResults (if yes, then abort the process) if (destroying) return; // add results searchResults->addSearchResults(results); searchResults->setSummary(results.getSummary()); // add new search block emit addNewSearchBlock(plugin); // has results? if (searchResults->getSearchResultCount() == 0) { // emit add no results emit searchResultAdded(NULL); // next search... continue; } // show results for (int n = lastCount; n < searchResults->getSearchResultCount(); n++) { // emit add result emit searchResultAdded(searchResults->getSearchResult(n)); // add to previews download previews imageCatcher->addPreview(searchResults->getSearchResult(n)); } } // update last count lastCount = searchResults->getSearchResultCount(); } // search finished emit searchFinished(); }
bool NavOneSearchHandler::handleOneSearch( NavRequestData& rd ) { if ( !checkExpectations( rd.params, rd.reply ) ) { return false; } // The user UserUser* user = rd.session->getUser()->getUser(); uint32 startTime = TimeUtility::getCurrentTime(); uint32 now = TimeUtility::getRealTime(); bool ok = true; // AURA set< uint32 >* allowedMaps = NULL; if ( !m_thread->getMapIdsForUserRegionAccess( user, allowedMaps, now, rd.urmask ) ) { mc2log << warn << "handleOneSearch: " << "getMapIdsForUserRegionAccess failed. "; if ( TimeUtility::getCurrentTime() - startTime > 3000 ) { rd.reply->setStatusCode( NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT ); mc2log << "Timeout"; } else { rd.reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK ); mc2log << "Error"; } mc2log << endl; ok = false; } delete allowedMaps; // Start parameter printing mc2log << info << "handleOneSearch:"; CompactSearch params; params.m_oneResultList = true; params.m_itemInfoFilter = ItemInfoEnums::OneSearch_All; params.m_language = rd.clientLang; mc2log << " Lang " << StringTable::getString( StringTable::getLanguageAsStringCode( rd.stringtClientLang ), StringTable::ENGLISH ); if ( getParam( 6805, params.m_round, rd.params ) ) { mc2log << " Round " << params.m_round; } if ( getParam( 6804, params.m_maxHits, rd.params ) ) { mc2log << " MAX " << params.m_maxHits; } if ( getParam( 6800, params.m_what, rd.params ) ) { mc2log << " What " << params.m_what; } if ( NavParamHelper::getMC2CoordAndAngle( rd.params.getParam( 6802 ), params.m_location.m_coord, params.m_location.m_angle ) ) { mc2log << " Pos " << params.m_location.m_coord; } if ( getParam( 6803, params.m_distance, rd.params ) ) { mc2log << " Dist " << params.m_distance; } else if ( params.m_location.isValid() ) { // default 100km for distance params.m_distance = 100000; mc2log << " Dist " << params.m_distance; } if ( ! getParam( 6806, params.m_includeInfoItem, rd.params ) ) { params.m_includeInfoItem = true; } if ( params.m_includeInfoItem ) { mc2log << " include info fields "; } // Get the sorting type params.m_sorting = SearchTypes::DistanceSort; int32 sortType; if ( getParam( 6807, sortType, rd.params ) ) { mc2log << " Sort " << sortType; if( sortType == 1 ) { params.m_sorting = SearchTypes::AlphaSort; } } // Search category const NParam* p = rd.params.getParam( 6801 ); if ( p != NULL ) { uint32 length = p->getLength(); params.m_categoryIDs.resize( length ); for ( uint32 i = 0; i < length; ++i ) { params.m_categoryIDs.push_back( p->getInt32( i ) ); } } if ( rd.reqVer >= 2 ) { if ( getParam( 6808, params.m_where, rd.params ) ) { mc2log << " Where " << params.m_where; } if ( getParam( 6809, params.m_topRegionID, rd.params ) ) { mc2log << " TopRegionID " << params.m_topRegionID; } int32 searchType; if ( getParam( 6810, searchType, rd.params ) ) { if ( searchType == 0x1 && params.m_round == 0 ) { mc2log << " Address search "; params.m_heading = 1; // Address heading } } } // strip any leading and trailing white space from input params.cleanInput(); // Validate input fields if ( ! params.validInput() ) { rd.reply->setStatusCode( NavReplyPacket::NAV_STATUS_PARAMETER_INVALID ); rd.reply->setStatusMessage( "Invalid input" ); ok = false; } // End parameter printing mc2log << endl; // Set end index from max nbr hits and start index params.m_startIndex = 0; params.m_endIndex = params.m_maxHits - 1; // Make request typedef STLUtility::AutoContainerMap< SearchParserHandler::SearchResults > SearchResults; SearchResults results; if ( ok ) { results = m_thread->getSearchHandler().compactSearch( params ); for ( SearchResults::const_iterator it = results.begin() ; it != results.end() ; ++it ) { if ( (*it).second->getSearchResultRequest()->getStatus() != StringTable::OK ) { mc2log << "handleOneSearch: compactSearch Heading " << (*it).first << " failed: "; if ( (*it).second->getSearchResultRequest()->getStatus() == StringTable::TIMEOUT_ERROR ) { mc2log << " REQUEST_TIMEOUT"; rd.reply->setStatusCode( NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT ); } else if ( (*it).second->getSearchResultRequest()->getStatus() == StringTable::OUTSIDE_ALLOWED_AREA ) { mc2log << " OUTSIDE_ALLOWED_AREA"; rd.reply->setStatusCode( NavReplyPacket::NAV_STATUS_OUTSIDE_ALLOWED_AREA ); } else { mc2log << " NOT_OK"; rd.reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK ); } if ( params.m_round == 1 && (*it).second->getSearchResultRequest()->getStatus() != StringTable::OUTSIDE_ALLOWED_AREA ) { mc2log << " BUT round 1 (ExternalSearch) so we ignore"; rd.reply->setStatusCode( NavReplyPacket::NAV_STATUS_OK ); } else { ok = false; } mc2log << endl; } } } // Put reply together if ( ok ) { // one search only returns one heading in the list... SearchResults::const_iterator it = results.begin(); if ( it != results.end() ) { const SearchResultRequest* match = (*it).second->getSearchResultRequest(); const vector<VanillaMatch*>& matches = match->getMatches(); uint32 numberMatches = MIN( params.m_maxHits, matches.size() ); rd.rparams.addParam( NParam( 6900, numberMatches ) ); rd.rparams.addParam( NParam( 6901, match->getTotalNbrMatches() ) ); if ( numberMatches > 0 ) { using namespace OneSearchUtils; BinarySearchResult binaryResult; serializeResults( matches.begin(), matches.begin() + numberMatches, m_thread->getSearchHandler(), &binaryResult ); // Add SearchStringTable addDataBuffer( 6902, rd.rparams, binaryResult.m_stringTable.get() ); // Add AreaTable addDataBuffer( 6903, rd.rparams, binaryResult.m_areaTable.get() ); // Add infoItemTable addDataBuffer( 6904, rd.rparams, binaryResult.m_infoItemTable.get() ); // Add Matches addDataBuffer( 6905, rd.rparams, binaryResult.m_matchesTable.get() ); } else { // No hits. Add empty arrays rd.params.addParam( NParam( 6902 ) ); rd.params.addParam( NParam( 6903 ) ); rd.params.addParam( NParam( 6904 ) ); rd.params.addParam( NParam( 6905 ) ); } } } return ok; }
// recursive function which does all search logic void DFBB(StarcraftState & s, int depth) { // increase the node expansion count nodesExpanded++; // if we have constraints and they are not met if (params.useConstraints && !s.meetsConstraints(params.ssc)) { // this state is not legal return; } // the time at which the last thing in the queue will finish int finishTime = s.getLastFinishTime(); /*int lookupVal = TT.lookup(s.hashAllUnits(1), s.hashAllUnits(2)); if (lookupVal != -1 && lookupVal < finishTime) { ttcuts++; //return; } TT.save(s.hashAllUnits(1), s.hashAllUnits(2), finishTime);*/ // if we already have completed the units for the goal, don't worry about last finish time if (s.meetsGoalCompleted(params.goal)) { finishTime = s.getCurrentFrame(); } // if we have met the goal, we're good if (s.meetsGoal(params.goal)) { // if it's better than the current best solution, set the new best if (finishTime < upperBound)// || ((finishTime == upperBound) && (s.getWorkerCount() > winnerWorkerCount))) { // set the winning info upperBound = finishTime; winner = s; winnerFound = true; winnerWorkerCount = s.getWorkerCount(); results = SearchResults(true, upperBound, nodesExpanded, searchTimer.getElapsedTimeInMilliSec(), s.getBuildOrder()); results.upperBound = s.calculateUpperBoundHeuristic(params.goal); results.lowerBound = s.eval(params.goal); results.avgBranch = numChildren / (double)numGenerations; results.minerals = s.getFinishTimeMinerals(); results.gas = s.getFinishTimeGas(); results.saveState = SearchSaveState(getBuildOrder(s), upperBound); //graphVizOutput(s, true); results.printResults(true); s.printData(); return; } } // if we are using search timeout and we are over the limit // (nodesExpanded % 1000 == 0) only checks the time every 1000 expansions, since it is slow if (params.searchTimeLimit && (nodesExpanded % 200 == 0) && (searchTimer.getElapsedTimeInMilliSec() > params.searchTimeLimit)) { results.saveState = SearchSaveState(getBuildOrder(s), upperBound); //results.saveState.print(); // throw an exception to unroll the recursion throw 1; } // get the legal action set ActionSet legalActions = s.getLegalActions(params.goal); // only use relevant actions legalActions = legalActions & relevantActions; // if we enabled the supply bounding flag if (params.useSupplyBounding) { // if we are more than 2 supply providers in the lead if ((s.getMaxSupply() - s.getCurrentSupply()) >= params.supplyBoundingThreshold*DATA[DATA.getSupplyProvider()].supplyProvided()) { // make supply providers illegal legalActions.subtract(DATA.getSupplyProvider()); } } // if we enabled the always make workers flag, and workers are legal if (params.useAlwaysMakeWorkers && !params.goal[DATA.getWorker()] && legalActions[DATA.getWorker()]) { ActionSet tempLegal(legalActions); ActionSet legalBeforeWorker; // compute when the next worker will be trainable int workerReady = s.resourcesReady(DATA.getWorker()); // for each other legal action while (!tempLegal.isEmpty()) { Action nextAction = tempLegal.popAction(); // if the action will be ready before the next worker if (s.resourcesReady(nextAction) <= workerReady) { // it's legal legalBeforeWorker.add(nextAction); } } // update the legal actions legalActions = legalBeforeWorker; } // if we enabled the use worker cutoff flag and we're above the cutoff if (params.useWorkerCutoff && s.getCurrentFrame() > (params.workerCutoff * upperBound)) { // workers are no longer legal legalActions.subtract(DATA.getWorker()); // if we have enough supply for the remaining goal if (s.hasEnoughSupplyForGoal(params.goal)) { // make supply providers illegal legalActions.subtract(DATA.getSupplyProvider()); } } // if we have children, update the counter if (!legalActions.isEmpty()) { numGenerations += 1; numChildren += legalActions.numActions(); } // load the save state if we are using it if (params.useSaveState && !finishedLoadingSaveState) { // if we are under the saved depth, load accordingly if (depth < params.saveState.getDepth()) { // pop actions until the NEXT action is the one we want to start on while (!legalActions.isEmpty() && legalActions.nextAction() != params.saveState[depth]) { legalActions.popAction(); } } // if we are over the depth, we are finished loading else { finishedLoadingSaveState = true; } } // children of this state in the search std::vector<StarcraftState> childStates; // while there are still legal actions to perform while (!legalActions.isEmpty()) { // get the next action Action nextAction = legalActions.popAction(); // when this action would finish int actionFinishTime = s.resourcesReady(nextAction) + DATA[nextAction].buildTime(); // heuristic value of the goal state int heuristicTime = s.getCurrentFrame() + s.eval(params.goal, params.useLandmarkLowerBoundHeuristic); // the h value for this node int h = (actionFinishTime > heuristicTime) ? actionFinishTime : heuristicTime; // primary cut-off, very quick heuristic if (h <= upperBound) { bool stillLegal = true; StarcraftState child(s); // set the repetitions if we are using repetitions, otherwise set to 1 int repeat = params.useRepetitions ? params.getRepetitions(nextAction) : 1; // if we are using increasing repetitions if (params.useIncreasingRepetitions) { // if we don't have the threshold amount of units, use a repetition value of 1 repeat = child.getNumUnits(nextAction) >= params.getRepetitionThreshold(nextAction) ? repeat : 1; } // make sure we don't repeat to more than we need for this unit type if (params.goal.get(nextAction)) { repeat = (std::min)(repeat, params.goal.get(nextAction) - child.getNumUnits(nextAction)); } else if (params.goal.getMax(nextAction)) { repeat = (std::min)(repeat, params.goal.getMax(nextAction) - child.getNumUnits(nextAction)); } // limit repetitions to how many we can make based on current used supply if (DATA[nextAction].supplyRequired() > 0) { int haveSupplyFor = (s.getMaxSupply() + s.getSupplyInProgress() - s.getCurrentSupply()) / DATA[nextAction].supplyRequired(); repeat = (std::min)(repeat, haveSupplyFor); } // if we're not finished loading the state, repeat value is 1 if (params.useSaveState && !finishedLoadingSaveState) { repeat = 1; } // for each repetition of this action for (int r = 0; r < repeat; ++r) { // if the action is still legal if (child.isLegal(nextAction, params.goal)) { int readyTime = child.resourcesReady(nextAction); child.doAction(nextAction, readyTime); } // if it's not legal, break the chain else { stillLegal = false; break; } } // if all actions in a row are legal, recurse on the child if (stillLegal) { child.setParent(&s); child.setActionPerformedK((UnitCountType)repeat); //DFBB(child, depth+1); childStates.push_back(child); } } } //std::sort(childStates.begin(), childStates.end(), StarcraftStateCompare<StarcraftStateType>(params)); //std::random_shuffle(childStates.begin(), childStates.end()); for (size_t i(0); i<childStates.size(); ++i) { DFBB(childStates[i], depth+1); } }