void TabuSearch(){ int debug; int number_of_iterations = 100; int TabuLength = n; get_first_path(); vector<vector<int> > tabuList(TabuLength, std::vector<int>(TabuLength)); vector <int> bestSol((int)current_path.size()); bestSol = current_path; int shortest_path = GetTotalDistance(current_path); for (int i = 0; i < number_of_iterations;i++) { current_path = getBestNeighbour(tabuList, current_path); int currCost = GetTotalDistance(current_path); if (currCost < shortest_path) { bestSol = current_path; shortest_path = currCost; } } printf("shortest_path = %d", shortest_path); getchar(); getchar(); }
Data MatrixGraph::tabuSearch(uint tabuListSize, uint iterations) { clock_t overallTime = clock(); initRand(); if (!iterations) iterations = 1 << 10; //iterations = 50; stringstream results; vector<uint> currentPath, bestPath; currentPath.reserve(vertexNumber), bestPath.reserve(vertexNumber); //TabuArray tabuList(vertexNumber, tabuListSize); TabuList tabuList(tabuListSize); uint currentCost = 0, bestCost = 0, diverseLimit = (iterations >> 4) + 1, noChange = 0; // 1 - Create an initial solution(could be created randomly), now call it the current solution. for (uint i = 0; i < vertexNumber; ++i) currentPath.push_back(i); currentCost = calculateCost(currentPath); bestPath = currentPath; bestCost = currentCost; for (uint i = 0; i < iterations; ++i) { // 2 - Find the best neighbor of the current solution by applying certain moves. currentCost = getBestNeighbour(tabuList, currentPath); // 3 - If the best neighbor is reached my performing a non - tabu move, accept as the new current solution. // else, find another neighbor(best non - tabu neighbour). if (currentCost < bestCost) { bestPath = currentPath; bestCost = currentCost; noChange = 0; } else { if (++noChange > diverseLimit) { random_shuffle(currentPath.begin(), currentPath.end()); currentCost = calculateCost(currentPath); tabuList.clear(); noChange = 0; } } } // 4 - If maximum number of iterations are reached(or any other stopping condition), go to 5, else go to 2. // 5 - Globally best solution is the best solution we found throughout the iterations. double duration = (clock() - overallTime) / (double)CLOCKS_PER_SEC; results << "Koszt drogi: " << bestCost << "\nCalkowity czas trwania: " << duration << " sekund\n"; return Data(bestPath, bestCost, results.str(), duration); }
PSchedule Schedule :: localSearchKS(ParamsKS params, int *numberOfGeneratedSchedules) { function<PVectorJobs(PARAMETERS_OF_SELECTING_FUNCTION)> functionForSelecting = [params](PARAMETERS_OF_SELECTING_FUNCTION) -> PVectorJobs { return selectJobsViaKP(jobs, schedule, time, timeForStart, params.probabilityKP); }; TabuList tabuList(params.tabuListSize); int stepsNoChange = 0; // Number of steps without changing neighborhood NeighborhoodType currentNeighborhoodType = NeighborhoodTypeEarly; PSchedule schedule = shared_from_this(); // Start from current schedule PSchedule record = schedule; tabuList.add(schedule->sumOfStarts()); for (int iteration = 0; iteration < params.maxIterationNumber; iteration++) { #ifdef LOG_TO_CONSOL_SCHEDULE_H LOG("iterations: " << (float)iteration/params.maxIterationNumber * 100 << "%" << " record = " << record->duration()); #endif // intensification if (params.numberOfReturnsToRecord != 0 && (iteration % (params.maxIterationNumber / params.numberOfReturnsToRecord) == 0)) { schedule = record; } // currentNeighborhoodType if (stepsNoChange >= params.changingInterval) { switch (currentNeighborhoodType) { case NeighborhoodTypeEarly: { currentNeighborhoodType = NeighborhoodTypeLate; break; } case NeighborhoodTypeLate: { currentNeighborhoodType = NeighborhoodTypeEarly; break; } } stepsNoChange = 0; } // allNeighbors shared_ptr<vector<PSchedule>> allNeighbors = schedule->neighboringSchedules(currentNeighborhoodType, functionForSelecting); (*numberOfGeneratedSchedules) += allNeighbors->size(); // neighborsWithoutTabu auto neighborsWithoutTabu = shared_ptr<vector<PSchedule>>(new vector<PSchedule>(0)); neighborsWithoutTabu->reserve(allNeighbors->size()); while (neighborsWithoutTabu->size() == 0 && tabuList.size() != 0) { for (auto &neighbor : *allNeighbors) { if (!tabuList.containTabu(neighbor->sumOfStarts())) { neighborsWithoutTabu->push_back(neighbor); } } if (neighborsWithoutTabu->size() == 0) { tabuList.changeMaxSize(tabuList.maxSize() - 1); } } if (neighborsWithoutTabu->size() == 0 && tabuList.size() == 0) { neighborsWithoutTabu->insert(neighborsWithoutTabu->begin(), allNeighbors->begin(), allNeighbors->end()); } // neighbors auto neighbors = shared_ptr<vector<PSchedule>>(new vector<PSchedule>(0)); neighbors->reserve(neighborsWithoutTabu->size()); for (auto &neighbor : *neighborsWithoutTabu) { if (Random :: randomFloatFrom0To1() < params.probabilitySN) { neighbors->push_back(neighbor); } } if (neighbors->size() == 0) { long randIndex = Random :: randomLong(0, neighborsWithoutTabu->size() - 1); neighbors->push_back((*neighborsWithoutTabu)[randIndex]); } // minNeighbor PSchedule minNeighbor = nullptr; int minNeighborDuration = INT_MAX; for (auto &neighbor : *neighbors) { int neighborDuration = neighbor->duration(); if (neighborDuration < minNeighborDuration) { minNeighbor = neighbor; minNeighborDuration = neighborDuration; } } // Update record, schedule, tabuList #warning (<=) or (<) ? May be move it to parametes of method? if (minNeighborDuration <= record->duration()) record = minNeighbor; schedule = minNeighbor; tabuList.add(minNeighbor->sumOfStarts()); // Update stepsNoChange stepsNoChange++; } return record; }