ConstSolutionPtr IpoptEngine::getSolution() { if (sol_) { return sol_; } return SolutionPtr(); // NULL }
/** * Implementation of the Clarke and Wright savings algorithm * This function modifies an existing solution by merging tours from the same depot if this results in a net * cost reduction. The tours are merged in order of net reduction from highest to lowest. This is primarily * used to initiate the solver with a sensible first guess. */ SolutionPtr cw_savings(SolutionPtr prevsol) { set<TourPtr> newsol; for (auto depot : prevsol->get_problem()->get_depots()) { vector<TourPtr> tours_vec = prevsol->tours_from_depot(depot); set<TourPtr> tours(tours_vec.begin(), tours_vec.end()); while (true) { double reduction = -1; TourPtr left, right; for (auto t1 : tours) for (auto t2 : tours) { if (t1 == t2) continue; double test_reduction = triangle(*t1->last(), *depot, *t2->first()); // Only accept this merge if it doesn't break the daily cap condition if ( test_reduction > reduction && t1->duration() + t2->duration() - test_reduction <= prevsol->get_problem()->get_daily_cap()) { reduction = test_reduction; left = t1; right = t2; } } if (reduction >= 0) { tours.erase(left); tours.erase(right); tours.insert(TourPtr(new Tour(*left, *right))); } else break; } newsol.insert(tours.begin(), tours.end()); } return SolutionPtr(new Solution(prevsol->get_problem(), newsol)); }
typename ThetaStar<ProblemType, Hasher>::SolutionPtr ThetaStar<ProblemType, Hasher>::operator() ( const ProblemType& problem ) { SolutionPtr solution(nullptr); this->visits = 0; this->maxNodesInMemory = 0; NodePtr initialStateNode = this->createNode( problem.initialState() ); this->fringe->push(initialStateNode); //clock_t begin = clock(); while( !solution && !this->fringe->empty() ) { if(this->fringe->size() + this->closedList.size() > this->maxNodesInMemory) this->maxNodesInMemory = this->fringe->size() + this->closedList.size(); this->visits++; NodePtr currentNode = this->fringe->pop(); this->notifyNodeVisitListeners(currentNode); if( problem.isGoal( currentNode->getState() ) ) { solution = SolutionPtr(new SolutionType(currentNode)); continue; } std::pair<const State*, NodePtr> entry(¤tNode->getState(), currentNode); this->closedList.insert(entry); this->notifyNodeClosureListeners(currentNode); std::list<NodePtr>&& successors = this->expand(currentNode, problem); for(NodePtr node: successors) { auto nodeIt = this->closedList.find(&node->getState()); if(nodeIt == this->closedList.end()) { if(node->hasParent()) { if(node->getParent()->hasParent()) { auto grandParent = node->getParent()->getParent(); auto actionAndCost = (*lineOfSight)(node->getState(), grandParent->getState()); if(actionAndCost.first != nullptr) { node->setParent(grandParent, *actionAndCost.first, actionAndCost.second); } } } this->fringe->push(node); } } } //clock_t end = clock(); //double timeSpend = (double)(end - begin) / CLOCKS_PER_SEC; //std::cout << "Spent " << timeSpend << " seconds on " << visit << " visits (" << visit/timeSpend << " n/s)" << std::endl; this->cleanUp(); return solution; }