|
@@ -428,20 +428,15 @@ std::vector<unsigned> Graph::travellingSalesmanTabuSearch(Graph &graph, unsigned
|
428
|
428
|
// Implementacja: Jan Potocki 2019
|
429
|
429
|
std::vector<unsigned> startVertexVector;
|
430
|
430
|
std::vector<std::thread> threadsVector;
|
431
|
|
- std::vector<std::vector<unsigned>> resultsVector(threadsNumber);
|
432
|
431
|
|
433
|
|
- std::vector<int> resultsLength(threadsNumber);
|
434
|
|
- std::vector<unsigned> optimalResult;
|
435
|
|
- int optimalResultIndex;
|
436
|
|
- int optimalResultLength;
|
|
432
|
+ std::mutex globalOptimumMutex;
|
|
433
|
+ std::vector<unsigned> globalOptimum;
|
|
434
|
+ unsigned globalOptimumLength = -1;
|
437
|
435
|
|
438
|
436
|
std::random_device randomSrc;
|
439
|
437
|
std::default_random_engine randomGen(randomSrc());
|
440
|
438
|
std::uniform_int_distribution<> vertexDist(0, graph.vertexNumber - 1);
|
441
|
439
|
|
442
|
|
- std::mutex globalOptimumMutex;
|
443
|
|
- unsigned globalOptimum = -1;
|
444
|
|
-
|
445
|
440
|
// Petla uruchamiajaca watki
|
446
|
441
|
for(int i = 0; i < threadsNumber; i++)
|
447
|
442
|
{
|
|
@@ -481,32 +476,17 @@ std::vector<unsigned> Graph::travellingSalesmanTabuSearch(Graph &graph, unsigned
|
481
|
476
|
}
|
482
|
477
|
|
483
|
478
|
// Uruchomienie watku
|
484
|
|
- 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)), std::ref(globalOptimum), std::ref(globalOptimumMutex)));
|
|
479
|
+ threadsVector.push_back(std::thread(Graph::travellingSalesmanTabuSearchEngine, std::ref(graph), tabuSteps, diversification, iterationsToRestart, minStopTime, startRoute, std::ref(globalOptimum), std::ref(globalOptimumLength), std::ref(globalOptimumMutex)));
|
485
|
480
|
}
|
486
|
481
|
|
487
|
482
|
// Petla potwierdzajaca zakonczenie watkow
|
488
|
483
|
for(int i = 0; i < threadsNumber; i++)
|
489
|
484
|
threadsVector.at(i).join();
|
490
|
485
|
|
491
|
|
- // Przegladanie wszystkich rozwiazan i wybor optymalnego
|
492
|
|
- optimalResultIndex = 0;
|
493
|
|
- optimalResultLength = resultsLength.at(0);
|
494
|
|
-
|
495
|
|
- for(int i = 0; i < threadsNumber; i++)
|
496
|
|
- {
|
497
|
|
- if(resultsLength.at(i) < optimalResultLength)
|
498
|
|
- {
|
499
|
|
- optimalResultIndex = i;
|
500
|
|
- optimalResultLength = resultsLength.at(i);
|
501
|
|
- }
|
502
|
|
- }
|
503
|
|
-
|
504
|
|
- optimalResult = resultsVector.at(optimalResultIndex);
|
505
|
|
-
|
506
|
|
- return optimalResult;
|
|
486
|
+ return globalOptimum;
|
507
|
487
|
}
|
508
|
488
|
|
509
|
|
-void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps, bool diversification, int iterationsToRestart, unsigned minStopTime, std::vector<unsigned> startRoute, std::vector<unsigned> &result, int &resultLength, unsigned &globalOptimum, std::mutex &globalOptimumMutex)
|
|
489
|
+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)
|
510
|
490
|
{
|
511
|
491
|
// ALGORYTM oparty na metaheurystyce tabu search z dywersyfikacja i sasiedztwem typu swap
|
512
|
492
|
// Rdzen przeznaczony do uruchamiania jako jeden watek
|
|
@@ -580,9 +560,16 @@ void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps,
|
580
|
560
|
}
|
581
|
561
|
|
582
|
562
|
// Kryterium aspiracji...
|
583
|
|
- if(tabu == true && neighbourRouteLength >= optimalRouteLength)
|
|
563
|
+ globalOptimumMutex.lock();
|
|
564
|
+ if(tabu == true && neighbourRouteLength >= globalOptimumLength)
|
|
565
|
+ {
|
|
566
|
+ globalOptimumMutex.unlock();
|
|
567
|
+
|
584
|
568
|
// ...jezeli niespelnione - pomijamy ruch
|
585
|
569
|
continue;
|
|
570
|
+ }
|
|
571
|
+ else
|
|
572
|
+ globalOptimumMutex.unlock();
|
586
|
573
|
|
587
|
574
|
if(nextRouteLength == -1)
|
588
|
575
|
{
|
|
@@ -606,19 +593,21 @@ void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps,
|
606
|
593
|
// Jan Potocki 2019
|
607
|
594
|
|
608
|
595
|
globalOptimumMutex.lock();
|
609
|
|
- if(globalOptimum == -1)
|
|
596
|
+ if(globalOptimumLength == -1)
|
610
|
597
|
{
|
611
|
|
- globalOptimum = nextRouteLength;
|
|
598
|
+ globalOptimumLength = nextRouteLength;
|
|
599
|
+ globalOptimum = nextRoute;
|
612
|
600
|
optimalRoute = nextRoute;
|
613
|
601
|
|
614
|
602
|
// Reset licznika
|
615
|
603
|
stopCounter = 0;
|
616
|
604
|
|
617
|
|
- std::cout << "Nowa najlepsza trasa: " << globalOptimum << std::endl;
|
|
605
|
+ std::cout << "Nowa najlepsza trasa: " << globalOptimumLength << std::endl;
|
618
|
606
|
}
|
619
|
|
- else if(globalOptimum > nextRouteLength)
|
|
607
|
+ else if(globalOptimumLength > nextRouteLength)
|
620
|
608
|
{
|
621
|
|
- globalOptimum = nextRouteLength;
|
|
609
|
+ globalOptimumLength = nextRouteLength;
|
|
610
|
+ globalOptimum = nextRoute;
|
622
|
611
|
optimalRoute = nextRoute;
|
623
|
612
|
|
624
|
613
|
// Zaplanowanie intensyfikacji przy znalezieniu nowego optimum
|
|
@@ -627,7 +616,7 @@ void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps,
|
627
|
616
|
// Reset licznika
|
628
|
617
|
stopCounter = 0;
|
629
|
618
|
|
630
|
|
- std::cout << "Nowa najlepsza trasa: " << globalOptimum << std::endl;
|
|
619
|
+ std::cout << "Nowa najlepsza trasa: " << globalOptimumLength << std::endl;
|
631
|
620
|
}
|
632
|
621
|
globalOptimumMutex.unlock();
|
633
|
622
|
|
|
@@ -698,6 +687,5 @@ void Graph::travellingSalesmanTabuSearchEngine(Graph &graph, unsigned tabuSteps,
|
698
|
687
|
stopCounter = 0;
|
699
|
688
|
}
|
700
|
689
|
|
701
|
|
- result = optimalRoute;
|
702
|
|
- resultLength = optimalRouteLength;
|
|
690
|
+std::cout << std::endl;
|
703
|
691
|
}
|