Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- int TSP::tabuSearchBasicSwap(int n, bool save)
- {
- //struktura sąsiednich scierzek
- struct swapList
- {
- int a;
- int b;
- int improvment;
- };
- //lista tabu
- int ** tabu;
- for (int i = 0; i < instance.getSize();i++) {
- tabu[i] = new int[instance.getSize()];
- for (int j = i + 1; j < instance.getSize();j++) {
- tabu[i][j] = 0;
- }
- }
- //wstępnie nalepsza ścierzka i jej koszt
- int* best = bbFastBestPath();
- int bestCost = instance.calculateCost(best);
- //obecna scierzka
- int* current = bbFastBestPath();
- int currentCost = bestCost;
- //warunkiem stopu będzie ilość iteracji zadana w parametrze fubnkcji i domyślnie wynosząca 100
- while (n>0) {
- //krok 1
- //tworzenie sasiadow
- vector<swapList>neighbours;
- for(int i = 0 ; i < instance.getSize() ;i++)
- for (int j = i + 1 ; j < instance.getSize();j++) {
- swapList element;
- element.a = current[i];
- element.b = current[j];
- //ulepszenie wynosi nowy koszt odjąć stary
- element.improvment = swappedElementCost(i, j, current) - currentCost;
- neighbours.push_back(element);
- }
- cout << neighbours.size();
- for (int i = 0; i < neighbours.size(); i++) printf("[%3d,%3d : %2d]\n",neighbours[i].a, neighbours[i].b, neighbours[i].improvment);
- //krok 2
- //petla z wuybieranuiem sasiada:
- //najlepszy niezakazany, chyba że zakazany jest lepszy od best
- //teraz należy znaleźć najmniejszy
- bool foundSwap = false;
- //zmienna do akcji na sąsiedztwie
- int select;
- int indexOfBestImprovement=0;
- do {
- int bestNeighbour = neighbours[0].improvment;
- for (int i = 1; i < instance.getSize();i++)
- if (neighbours[i].improvment < bestNeighbour) {
- indexOfBestImprovement = i;
- bestNeighbour = neighbours[i].improvment;
- }
- //znalezlismy najmniejszy teraz sprawdzamy czy zgadza sie z kryterium aspiracji ponieważ jest to warunek nadrzędny nad listą tabu
- if (currentCost + neighbours[indexOfBestImprovement].improvment < bestCost) {
- select = 1;
- foundSwap = true;
- //jeżeli tabu zaprzecza to należy sprawdzic kryterium aspiracji
- //naszym kryterium
- }
- else if (tabu[neighbours[indexOfBestImprovement].a][neighbours[indexOfBestImprovement].b] < 1) {
- select = 2;
- foundSwap = true;
- //jeżeli kryterium aspiracji nie zatwierdza tej zmiany i tabu też się nie zgadza to szukamy kolejnego lokalnie najleopszego sąsiedztwa
- //czyli w kwesti implementacyjnej usuwamy ten element z listy i rozpartrujemy od nowa pętle do-while
- }
- else {
- neighbours.erase(neighbours.begin() + indexOfBestImprovement);
- }
- //mam zamiar nie doprowadzic do sytuacji gdy wszystkie swapy będą zakazane ponieważ kadencja zakazu będzie mniejsza od liczby elementów
- //czyli nie będzie sytuacji aby wszystkie ruchy na raz były zakazane
- //w przeciwnym razie jednak należy to tutaj uwzględnić, zawsze należy jakiegoś sąsiada wybrać
- } while (!foundSwap);
- //krok 3
- //aktualizacja
- //posłużymy się naszym selectem poniewaaż gdy trzeba nadpisać best to również trzeba nadpisać current więc swich z case3m bez breaka będzie elegancko wyglądał
- switch (select) {
- //1 oznacza że przebiło kryterium aspiracji dlatego warunek tabu nas nie interesuje, musimy nadpisać besty
- case 1:
- //przepisanie nowego besta
- for (int i = 0; i < instance.getSize();i++) best[i] = current[i];
- //zamiana elementow
- int tmp = best[neighbours[indexOfBestImprovement].a];
- best[neighbours[indexOfBestImprovement].a] = best[neighbours[indexOfBestImprovement].b];
- best[neighbours[indexOfBestImprovement].b] = tmp;
- //przypisanie najmniejszego kosztu
- bestCost = instance.calculateCost(best);
- //nadpisanie bestów oznacza ze current również będzie lepszy i przechodzimy do tego kroku, brak breaka sprawia że wykonujemy albo warunek 1 i 2 albo tylko 2
- case 2:
- //zamieniamy w currencie elementy tak jak dla besta
- int tmp = current[neighbours[indexOfBestImprovement].a];
- current[neighbours[indexOfBestImprovement].a] = current[neighbours[indexOfBestImprovement].b];
- current[neighbours[indexOfBestImprovement].b] = tmp;
- //nadpisujemy chwilowy koszt
- currentCost = instance.calculateCost(current);
- //nakładamy zakaz na zamiane tych 2 elementów na n/2(ale nie mniej niż jeden) ruchów NIE WIEM NA ILE NAKŁADAĆ
- //czyli implementacyjnie ustawiamy kolejne atrybuty na liście tabu;
- tabu[neighbours[indexOfBestImprovement].a][neighbours[indexOfBestImprovement].b] = n / 2 > 0 ? n / 2 : 1;
- tabu[neighbours[indexOfBestImprovement].b][neighbours[indexOfBestImprovement].a] = n / 2 > 0 ? n / 2 : 1;
- break;
- //nie widzę opcji dojścia turtaj z innym warunkiem select dlategop dla pewności zatrzymajmy funkcje z kodem błędu
- default:
- return -1;
- break;
- }
- //znaleźliśmy najmniejszy wykonaliśmy zamiane jeśli jakimś dziwnym trafem program się wywali to znaczy że wybór sąsiada szwankuje
- //po wyjkonaniu musimy zmniejszyć ilość interesujących nass iteracji
- n--;
- //i koniecznie zmniejszyć wartości listy tabu
- tabuDecrementation(tabu);
- }
- return bestCost;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement