std::vector<std::vector<SearchParameters> > Controller::runRouteSearch(SearchParameters parameters) { std::vector<std::vector<Path> > result = routeSearcher.searchRoutes(parameters.getStart(), parameters.getFinish(), parameters.toRouteCost()); std::vector<std::vector<SearchParameters> > routes; std::vector<std::vector<Path> >::iterator it; for (it = result.begin(); it != result.end(); it++) { std::vector<Path> current = (*it); std::vector<SearchParameters> route = std::vector<SearchParameters>(); for (std::vector<Path>::iterator iter = current.begin(); iter != current.end(); ++iter) { SearchParameters routeParams; routeParams.setStart(iter->getFrom().getId()); routeParams.setFinish(iter->getTo().getId()); routeParams.setMoney(parameters.getTravellersNumber()*(iter->getRouteCost().getMoneyCost())); routeParams.setTime(iter->getRouteCost().getTimeCost()); std::set<Interest> interests = iter->getRouteCost().getInterests(); std::set<Transport> transports = iter->getRouteCost().getTransport(); for (std::set<Interest>::iterator i = interests.begin(); i != interests.end(); ++i) { routeParams.addInterest(*i); } for (std::set<Transport>::iterator i = transports.begin(); i != transports.end(); ++i) { routeParams.addTransport(*i); } route.emplace_back(routeParams); } routes.emplace_back(route); } return routes; }
void testArmySearch() { //srand(time(NULL)); SearchParameters params; // params.initialState = openingBookStateGateway(); params.initialState = StarcraftState(true); params.initialUpperBound = 6000; params.goal = defaultProtossGoal(); params.useAlwaysMakeWorkers = true; params.useIncreasingRepetitions = true; params.setRepetitionThreshold(DATA.getSupplyProvider(), 1); params.setRepetitionThreshold(DATA.getWorker(), 8); params.setRepetitions( DATA.getAction(BWAPI::UnitTypes::Protoss_Probe), 2); params.setRepetitions( DATA.getAction(BWAPI::UnitTypes::Protoss_Pylon), 2); params.setRepetitions( DATA.getAction(BWAPI::UnitTypes::Protoss_Gateway), 1); params.setRepetitions( DATA.getAction(BWAPI::UnitTypes::Protoss_Zealot), 2); params.setRepetitions( DATA.getAction(BWAPI::UnitTypes::Protoss_Dragoon), 2); params.goal.setGoalMax( DATA.getAction(BWAPI::UnitTypes::Protoss_Probe), 16 ); params.goal.setGoalMax( DATA.getAction(BWAPI::UnitTypes::Protoss_Gateway), 4 ); params.goal.setGoalMax( DATA.getAction(BWAPI::UnitTypes::Protoss_Pylon), 4); ArmySearch search(params); SearchResults result = search.search(); printf("Search took %lf ms\n", result.timeElapsed); }
void MainWindow::showFullInfo() { QPushButton* b = qobject_cast<QPushButton *>(sender()); int index = b->property("index").toInt(); std::vector<SearchParameters> path = vvPaths.at(index); QString startName = QString::fromStdString(CityMap::Instance().getPlaceById(path.at(0).getStart()).getName()); QString finishName = QString::fromStdString(CityMap::Instance().getPlaceById(path.at(path.size() - 1).getFinish()).getName()); QString cost = QString::number(MainWindow::defineCost(path)); QString duration = MainWindow::defineDuration(path).toString(); std::vector<QString> stopsList; for(int i = 0; i < path.size(); i++) { SearchParameters sp = path.at(i); QString stopName = QString::fromStdString(CityMap::Instance().getPlaceById(sp.getStart()).getName()); stopsList.push_back(stopName); } // for(int i = 0; i < routesTableItem.pathVector.size(); i++) { // SearchParameters searchParams = routesTableItem.pathVector.at(i); // std::string str = CityMap::Instance().getPlaceById(searchParams.getStart()).getName(); // stopsList.push_back(QString::fromStdString(str)); // } stopsList.push_back(finishName); QString stopsStr; for(int i = 0; i < stopsList.size();i++) { stopsStr += QString::number(i+1); stopsStr += ") "; stopsStr += stopsList.at(i); stopsStr += "\n"; } QMessageBox::information(this, "Информация о маршруте", QString("\nИз: ") + startName + QString("\nВ: ") + finishName + QString("\nСтоимость: ") + cost + QString("\nВремя: ") + duration + QString("\nОстановки: \n") + stopsStr); }
void setRepetitions() { // build supply providers in 2's after the first params.setRepetitions(DATA.getSupplyProvider(), 2); params.setRepetitionThreshold(DATA.getSupplyProvider(), 1); // build workers in 2s params.setRepetitions(DATA.getWorker(), 2); // for each action for (Action a = 0; a < DATA.size(); ++a) { // if it's a non depot producing building build in 2s after the first if (DATA[a].canProduce() && !DATA[a].isResourceDepot()) { params.setRepetitions(a, 2); params.setRepetitionThreshold(a, 1); } } }
void MainWindow::runRouteSearching() { // Собрать всю информацию SearchParameters parameters; parameters.setStart(ui->startList->currentData().toInt()); parameters.setFinish(ui->finishList->currentData().toInt()); parameters.setTravellersNumber(ui->peopleCount->value()); parameters.setTime(ui->timeEdit->time()); if (ui->timeEdit->time() == QTime(0,0)) { QMessageBox::warning(this,"Ошибка в вводе праметров", "Не задано время! Ничего найдено не будет!"); } parameters.setMoney(ui->moneyCount->value()); int count = 0; for (int i = 0; i <= ENTERTAINMENT; i++) { if (interestsModel.item(i)->checkState()) { parameters.addInterest((Interest)i); count++; } } if (count == 0) { QMessageBox::warning(this,"Ошибка в вводе праметров", "Не выбрана ни одна категория интересов!"); } count = 0; for (int i = 0; i <= FOOT; i++) { if (transportModel.item(i)->checkState()) { parameters.addTransport((Transport)i); count++; } } if (count == 0) { QMessageBox::warning(this,"Ошибка в вводе праметров", "Не выбран ни один вид транспорта!"); } std::vector<std::vector<SearchParameters> > routes = controller.runRouteSearch(parameters); fillRoutesList(routes); }
// recursive function which does all search logic void DFBB(StarcraftStateType & s, int depth) { // increase the node expansion count nodesExpanded++; //graphVizOutput(s, false); // the time at which the last thing in the queue will finish int finishTime = s.getLastFinishTime(); if (finishTime >= upperBound) { return; } 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); int bucket = getBucket(finishTime); int armyValue = s.getArmyValue(); if (armyValue > armyValues[bucket]) { armyValues[bucket] = armyValue; buildOrders[bucket] = getBuildOrder(s); } // if we are using search timeout and we are over the limit if (params.searchTimeLimit && (nodesExpanded % 1000 == 0) && (searchTimer.getElapsedTimeInMilliSec() > params.searchTimeLimit)) { // throw an exception to unroll the recursion throw 1; } // get the legal action set ActionSet legalActions = s.getLegalActionsMonteCarlo(params.goal); // if we have children, update the counter if (!legalActions.isEmpty()) { numGenerations += 1; numChildren += legalActions.numActions(); } // while there are still legal actions to perform while (!legalActions.isEmpty()) { // get the next action Action nextAction = legalActions.popAction(); bool stillLegal = true; StarcraftStateType child(s); // set the repetitions if we are using repetitions, otherwise set to 1 int repeat = params.useRepetitions ? params.getRepetitions(nextAction) : 1; // for each repetition of this action for (int r = 0; r < repeat; ++r) { // if the action is still legal if (child.isLegalMonteCarlo(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 (stillLegal) //{ child.setParent(&s); child.setActionPerformedK((UnitCountType)repeat); DFBB(child, depth+1); //} } }
void print() { params.initialState.printData(); params.print(); printf("\n\n"); }
// 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); } }