|
@@ -250,12 +250,7 @@ std::vector<unsigned> Graph::travellingSalesmanGreedy(Graph &graph, unsigned sta
|
250
|
250
|
// Implementacja: Jan Potocki 2017
|
251
|
251
|
std::vector<unsigned> route;
|
252
|
252
|
|
253
|
|
- // std::random_device randomSrc;
|
254
|
|
- // std::default_random_engine randomGen(randomSrc());
|
255
|
|
- // std::uniform_int_distribution<> vertexDist(0, graph.vertexNumber - 1);
|
256
|
|
-
|
257
|
|
- // Losowanie wierzcholka startowego
|
258
|
|
- //route.push_back(vertexDist(randomGen));
|
|
253
|
+ // Przypisanie wierzcholka startowego
|
259
|
254
|
route.push_back(startVertex);
|
260
|
255
|
|
261
|
256
|
for(int i = 0; i < graph.vertexNumber - 1; i++)
|
|
@@ -370,6 +365,8 @@ std::vector<unsigned> Graph::travellingSalesmanHybrid(Graph &graph)
|
370
|
365
|
// Znalezienie najkrotszej mozliwej jeszcze do uzycia krawedzi
|
371
|
366
|
unsigned consideredLength = graph.getWeight(route.back(), j);
|
372
|
367
|
|
|
368
|
+ // PEA 2 Plus
|
|
369
|
+ // Jan Potocki 2019
|
373
|
370
|
if(minEdge == -1)
|
374
|
371
|
{
|
375
|
372
|
minEdge = consideredLength;
|
|
@@ -433,6 +430,7 @@ std::vector<unsigned> Graph::travellingSalesmanTabuSearch(Graph &graph, unsigned
|
433
|
430
|
std::vector<unsigned> startVertexVector;
|
434
|
431
|
std::vector<std::thread> threadsVector;
|
435
|
432
|
std::vector<std::vector<unsigned>> resultsVector(threadsNumber);
|
|
433
|
+
|
436
|
434
|
std::vector<int> resultsLength(threadsNumber);
|
437
|
435
|
std::vector<unsigned> optimalResult;
|
438
|
436
|
int optimalResultIndex;
|
|
@@ -442,14 +440,18 @@ std::vector<unsigned> Graph::travellingSalesmanTabuSearch(Graph &graph, unsigned
|
442
|
440
|
std::default_random_engine randomGen(randomSrc());
|
443
|
441
|
std::uniform_int_distribution<> vertexDist(0, graph.vertexNumber - 1);
|
444
|
442
|
|
|
443
|
+ // Petla uruchamiajaca watki
|
445
|
444
|
for(int i = 0; i < threadsNumber; i++)
|
446
|
445
|
{
|
|
446
|
+ // Generowanie startowego rozwiazania...
|
447
|
447
|
std::vector<unsigned> startRoute;
|
448
|
448
|
unsigned startVertex;
|
449
|
449
|
bool startVertexUsed;
|
450
|
450
|
|
451
|
451
|
if(i < graph.vertexNumber)
|
452
|
452
|
{
|
|
453
|
+ // ...dopoki ma to sens - algorytmem zachlannym z innym wierzcholkiem startowym
|
|
454
|
+ // (dla kazdego watku)
|
453
|
455
|
do
|
454
|
456
|
{
|
455
|
457
|
startVertex = vertexDist(randomGen);
|
|
@@ -465,20 +467,26 @@ std::vector<unsigned> Graph::travellingSalesmanTabuSearch(Graph &graph, unsigned
|
465
|
467
|
}
|
466
|
468
|
} while(startVertexUsed == true);
|
467
|
469
|
|
|
470
|
+ // PEA 2 Plus
|
|
471
|
+ // Jan Potocki 2019
|
468
|
472
|
startVertexVector.push_back(startVertex);
|
469
|
473
|
startRoute = Graph::travellingSalesmanGreedy(graph, startVertex);
|
470
|
474
|
}
|
471
|
475
|
else
|
472
|
476
|
{
|
|
477
|
+ // ...jezeli wszystkie wierzcholki sa juz wykorzystane - w pelni losowo
|
473
|
478
|
startRoute = Graph::travellingSalesmanRandom(graph);
|
474
|
479
|
}
|
475
|
480
|
|
|
481
|
+ // Uruchomienie watku
|
476
|
482
|
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))));
|
477
|
483
|
}
|
478
|
484
|
|
|
485
|
+ // Petla potwierdzajaca zakonczenie watkow
|
479
|
486
|
for(int i = 0; i < threadsNumber; i++)
|
480
|
487
|
threadsVector.at(i).join();
|
481
|
488
|
|
|
489
|
+ // Przegladanie wszystkich rozwiazan i wybor optymalnego
|
482
|
490
|
optimalResultIndex = 0;
|
483
|
491
|
optimalResultLength = resultsLength.at(0);
|
484
|
492
|
|
|
@@ -592,6 +600,8 @@ void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps,
|
592
|
600
|
}
|
593
|
601
|
|
594
|
602
|
currentRoute = nextRoute;
|
|
603
|
+ // PEA 2 Plus
|
|
604
|
+ // Jan Potocki 2019
|
595
|
605
|
|
596
|
606
|
if(optimalRouteLength == -1)
|
597
|
607
|
{
|
|
@@ -606,7 +616,7 @@ void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps,
|
606
|
616
|
optimalRouteLength = nextRouteLength;
|
607
|
617
|
optimalRoute = nextRoute;
|
608
|
618
|
|
609
|
|
- // Zaplanowanie intensyfikacji
|
|
619
|
+ // Zaplanowanie intensyfikacji przy znalezieniu nowego optimum
|
610
|
620
|
intensification = true;
|
611
|
621
|
|
612
|
622
|
// Reset licznika
|
|
@@ -658,14 +668,18 @@ void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps,
|
658
|
668
|
{
|
659
|
669
|
if(intensification == true)
|
660
|
670
|
{
|
661
|
|
- // Intensyfikacja przeszukiwania przy ostatnim minimum
|
|
671
|
+ // Intensyfikacja przeszukiwania przez skrócenie kadencji
|
|
672
|
+ // (jezeli w ostatnim przebiegu znaleziono nowe minimum)
|
662
|
673
|
currentRoute = optimalRoute;
|
663
|
674
|
currentTabuSteps = tabuSteps / 4;
|
664
|
675
|
intensification = false;
|
|
676
|
+ // PEA 2 Plus
|
|
677
|
+ // Jan Potocki 2019
|
665
|
678
|
}
|
666
|
679
|
else
|
667
|
680
|
{
|
668
|
|
- // Algorytm hybrydowy losowo-zachlanny
|
|
681
|
+ // W innym przypadku wlasciwa dywersyfikacja przez wygenerowanie nowego
|
|
682
|
+ // rozwiazania startowego algorytmem hybrydowym losowo-zachlannym
|
669
|
683
|
currentRoute = Graph::travellingSalesmanHybrid(graph);
|
670
|
684
|
currentTabuSteps = tabuSteps;
|
671
|
685
|
intensification = false;
|