Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3c900e57a3 | |||
| 6d562fb2e3 | |||
| b2517f51f2 | |||
| 20160689f4 | |||
| 6cab940785 | |||
| c10d296d82 | |||
| 5d78916930 | |||
| b577fd6c13 | |||
| 74e1d0be8e | |||
| 420ee4f275 |
@@ -5,7 +5,6 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
Graph::Graph()
|
Graph::Graph()
|
||||||
@@ -429,12 +428,10 @@ std::vector<unsigned> Graph::travellingSalesmanTabuSearch(Graph &graph, unsigned
|
|||||||
// Implementacja: Jan Potocki 2019
|
// Implementacja: Jan Potocki 2019
|
||||||
std::vector<unsigned> startVertexVector;
|
std::vector<unsigned> startVertexVector;
|
||||||
std::vector<std::thread> threadsVector;
|
std::vector<std::thread> threadsVector;
|
||||||
std::vector<std::vector<unsigned>> resultsVector(threadsNumber);
|
|
||||||
|
|
||||||
std::vector<int> resultsLength(threadsNumber);
|
std::mutex globalOptimumMutex;
|
||||||
std::vector<unsigned> optimalResult;
|
std::vector<unsigned> globalOptimum;
|
||||||
int optimalResultIndex;
|
unsigned globalOptimumLength = -1;
|
||||||
int optimalResultLength;
|
|
||||||
|
|
||||||
std::random_device randomSrc;
|
std::random_device randomSrc;
|
||||||
std::default_random_engine randomGen(randomSrc());
|
std::default_random_engine randomGen(randomSrc());
|
||||||
@@ -479,32 +476,17 @@ std::vector<unsigned> Graph::travellingSalesmanTabuSearch(Graph &graph, unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Uruchomienie watku
|
// Uruchomienie watku
|
||||||
threadsVector.push_back(std::thread(Graph::travellingSalesmanTabuSearchEngine, std::ref(graph), tabuSteps, diversification, iterationsToRestart, minStopTime, startRoute, std::ref(resultsVector.at(i)), std::ref(resultsLength.at(i))));
|
threadsVector.push_back(std::thread(Graph::travellingSalesmanTabuSearchEngine, std::ref(graph), tabuSteps, diversification, iterationsToRestart, minStopTime, startRoute, std::ref(globalOptimum), std::ref(globalOptimumLength), std::ref(globalOptimumMutex)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Petla potwierdzajaca zakonczenie watkow
|
// Petla potwierdzajaca zakonczenie watkow
|
||||||
for(int i = 0; i < threadsNumber; i++)
|
for(int i = 0; i < threadsNumber; i++)
|
||||||
threadsVector.at(i).join();
|
threadsVector.at(i).join();
|
||||||
|
|
||||||
// Przegladanie wszystkich rozwiazan i wybor optymalnego
|
return globalOptimum;
|
||||||
optimalResultIndex = 0;
|
|
||||||
optimalResultLength = resultsLength.at(0);
|
|
||||||
|
|
||||||
for(int i = 0; i < threadsNumber; i++)
|
|
||||||
{
|
|
||||||
if(resultsLength.at(i) < optimalResultLength)
|
|
||||||
{
|
|
||||||
optimalResultIndex = i;
|
|
||||||
optimalResultLength = resultsLength.at(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
optimalResult = resultsVector.at(optimalResultIndex);
|
|
||||||
|
|
||||||
return optimalResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps, bool diversification, int iterationsToRestart, unsigned minStopTime, std::vector<unsigned> startRoute, std::vector<unsigned> &result, int &resultLength)
|
void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps, bool diversification, int iterationsToRestart, unsigned minStopTime, std::vector<unsigned> startRoute, std::vector<unsigned> &globalOptimum, unsigned &globalOptimumLength, std::mutex &globalOptimumMutex)
|
||||||
{
|
{
|
||||||
// ALGORYTM oparty na metaheurystyce tabu search z dywersyfikacja i sasiedztwem typu swap
|
// ALGORYTM oparty na metaheurystyce tabu search z dywersyfikacja i sasiedztwem typu swap
|
||||||
// Rdzen przeznaczony do uruchamiania jako jeden watek
|
// Rdzen przeznaczony do uruchamiania jako jeden watek
|
||||||
@@ -535,7 +517,9 @@ void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps,
|
|||||||
|
|
||||||
while(cheeseSupplied == true)
|
while(cheeseSupplied == true)
|
||||||
{
|
{
|
||||||
std::vector<unsigned> nextRoute;
|
std::vector<unsigned> nextRoute = currentRoute;
|
||||||
|
// ...na wszelki wypadek, gdyby cale sasiedztwo bylo na liscie tabu
|
||||||
|
// (zeby algorytm sie nie wywalil)
|
||||||
int nextRouteLength = -1;
|
int nextRouteLength = -1;
|
||||||
|
|
||||||
std::vector<unsigned> nextTabu(3, 0);
|
std::vector<unsigned> nextTabu(3, 0);
|
||||||
@@ -582,14 +566,8 @@ void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps,
|
|||||||
// ...jezeli niespelnione - pomijamy ruch
|
// ...jezeli niespelnione - pomijamy ruch
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(nextRouteLength == -1)
|
|
||||||
{
|
if(nextRouteLength == -1 || nextRouteLength > neighbourRouteLength)
|
||||||
nextRouteLength = neighbourRouteLength;
|
|
||||||
nextRoute = neighbourRoute;
|
|
||||||
nextTabu.at(1) = i;
|
|
||||||
nextTabu.at(2) = j;
|
|
||||||
}
|
|
||||||
else if(nextRouteLength > neighbourRouteLength)
|
|
||||||
{
|
{
|
||||||
nextRouteLength = neighbourRouteLength;
|
nextRouteLength = neighbourRouteLength;
|
||||||
nextRoute = neighbourRoute;
|
nextRoute = neighbourRoute;
|
||||||
@@ -623,13 +601,26 @@ void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps,
|
|||||||
stopCounter = 0;
|
stopCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Synchronizacja globalnie najlepszej trasy (1)
|
||||||
|
globalOptimumMutex.lock();
|
||||||
|
if(globalOptimumLength == -1 || globalOptimumLength > nextRouteLength)
|
||||||
|
{
|
||||||
|
globalOptimumLength = nextRouteLength;
|
||||||
|
globalOptimum = nextRoute;
|
||||||
|
|
||||||
|
onboardClock.stop();
|
||||||
|
std::cout << "Nowa najlepsza trasa: " << globalOptimumLength;
|
||||||
|
std::cout << " (w czasie " << onboardClock.read() << " s)" << std::endl;
|
||||||
|
}
|
||||||
|
globalOptimumMutex.unlock();
|
||||||
|
|
||||||
// Weryfikacja listy tabu...
|
// Weryfikacja listy tabu...
|
||||||
int tabuPos = 0;
|
int tabuPos = 0;
|
||||||
while(tabuPos < tabuArray.size())
|
while(tabuPos < tabuArray.size())
|
||||||
{
|
{
|
||||||
// ...aktualizacja kadencji na liscie tabu
|
// ...aktualizacja kadencji na liscie tabu
|
||||||
tabuArray.at(tabuPos).at(0)--;
|
tabuArray.at(tabuPos).at(0)--;
|
||||||
|
|
||||||
//...usuniecie zerowych kadencji
|
//...usuniecie zerowych kadencji
|
||||||
if(tabuArray.at(tabuPos).at(0) == 0)
|
if(tabuArray.at(tabuPos).at(0) == 0)
|
||||||
tabuArray.erase(tabuArray.begin() + tabuPos);
|
tabuArray.erase(tabuArray.begin() + tabuPos);
|
||||||
@@ -678,9 +669,27 @@ void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Synchronizacja globalnie najlepszej trasy (2)
|
||||||
|
globalOptimumMutex.lock();
|
||||||
|
optimalRouteLength = globalOptimumLength;
|
||||||
|
optimalRoute = globalOptimum;
|
||||||
|
globalOptimumMutex.unlock();
|
||||||
|
|
||||||
// W innym przypadku wlasciwa dywersyfikacja przez wygenerowanie nowego
|
// W innym przypadku wlasciwa dywersyfikacja przez wygenerowanie nowego
|
||||||
// rozwiazania startowego algorytmem hybrydowym losowo-zachlannym
|
// rozwiazania startowego algorytmem hybrydowym losowo-zachlannym
|
||||||
currentRoute = Graph::travellingSalesmanHybrid(graph);
|
// (ale nie znacznie gorszego niz juz znalezione)
|
||||||
|
int criticalLength = (15 * optimalRouteLength) / 10;
|
||||||
|
int currentRouteLength;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
currentRoute = Graph::travellingSalesmanHybrid(graph);
|
||||||
|
currentRouteLength = 0;
|
||||||
|
|
||||||
|
for(int i = 1; i < currentRoute.size(); i++)
|
||||||
|
currentRouteLength += graph.getWeight(currentRoute.at(i - 1), currentRoute.at(i));
|
||||||
|
} while(currentRouteLength > criticalLength);
|
||||||
|
|
||||||
currentTabuSteps = tabuSteps;
|
currentTabuSteps = tabuSteps;
|
||||||
intensification = false;
|
intensification = false;
|
||||||
}
|
}
|
||||||
@@ -689,7 +698,4 @@ void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps,
|
|||||||
// Reset licznika iteracji przed restartem
|
// Reset licznika iteracji przed restartem
|
||||||
stopCounter = 0;
|
stopCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = optimalRoute;
|
|
||||||
resultLength = optimalRouteLength;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef GRAPH_H
|
#ifndef GRAPH_H
|
||||||
#define GRAPH_H
|
#define GRAPH_H
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
|
||||||
class Graph
|
class Graph
|
||||||
@@ -25,7 +26,7 @@ class Graph
|
|||||||
unsigned vertexNumber;
|
unsigned vertexNumber;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps, bool diversification, int iterationsToRestart, unsigned minStopTime, std::vector<unsigned> startRoute, std::vector<unsigned> &result, int &resultLength);
|
static void travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps, bool diversification, int iterationsToRestart, unsigned minStopTime, std::vector<unsigned> startRoute, std::vector<unsigned> &globalOptimum, unsigned &globalOptimumLength, std::mutex &globalOptimumMutex);
|
||||||
|
|
||||||
class RouteComparison
|
class RouteComparison
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-2
@@ -31,7 +31,7 @@ unsigned tabuLength = 0;
|
|||||||
// Domyslny stan dywersyfikacji
|
// Domyslny stan dywersyfikacji
|
||||||
bool tabuDiversification = true;
|
bool tabuDiversification = true;
|
||||||
// Domyslne kryterium dywersyfikacji, liczba iteracji bez poprawy
|
// Domyslne kryterium dywersyfikacji, liczba iteracji bez poprawy
|
||||||
int tabuIterationsToRestart = 10000;
|
int tabuIterationsToRestart = 5000;
|
||||||
// Domyslny czas zatrzymania algorytmu tabu search [s]
|
// Domyslny czas zatrzymania algorytmu tabu search [s]
|
||||||
unsigned tabuStopTime = 60;
|
unsigned tabuStopTime = 60;
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ unsigned autoTabuLength(Graph &graph)
|
|||||||
{
|
{
|
||||||
unsigned computedTabuLength;
|
unsigned computedTabuLength;
|
||||||
|
|
||||||
computedTabuLength = (2 * graph.getVertexNumber() / 10) * 10;
|
computedTabuLength = 10 + (graph.getVertexNumber() / 10) * 10;
|
||||||
if(computedTabuLength == 0)
|
if(computedTabuLength == 0)
|
||||||
computedTabuLength = 10;
|
computedTabuLength = 10;
|
||||||
|
|
||||||
@@ -439,6 +439,7 @@ int main(int argc, char *argv[])
|
|||||||
// Wyswietlenie trasy
|
// Wyswietlenie trasy
|
||||||
unsigned distFromStart = 0;
|
unsigned distFromStart = 0;
|
||||||
unsigned length = 0;
|
unsigned length = 0;
|
||||||
|
cout << endl;
|
||||||
cout << route.at(0) << '\t' << length << '\t' << distFromStart << endl;
|
cout << route.at(0) << '\t' << length << '\t' << distFromStart << endl;
|
||||||
for(int i = 1; i < route.size(); i++)
|
for(int i = 1; i < route.size(); i++)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user