Simulated annealing algorithm (SAA) to solve TSP problem

Posted by hhisc383 on Tue, 03 Mar 2020 08:05:24 +0100

1. What is simulated annealing algorithm?

Simulated annealing algorithm (SAA) was first proposed by N.Metropolis in 1953.
It is said that he suddenly thought of this simulated annealing method when he took a bath. The principle of simulated annealing is starting from a higher initial temperature at the initial time, and the molecules in the material are in a random arrangement state. With the constant decrease of temperature coefficient, the molecules are gradually arranged in a low-energy state, and finally reach a certain stable state.

Physical annealing

To understand the simulated annealing algorithm, first of all, we need to know how to realize physical annealing. The process of physical annealing is roughly divided into three stages:

The process of heating up - we accelerate the thermal movement of molecules by heating continuously, so that the whole object is in a random and disordered state until the object is at an initial temperature T.

Constant temperature process - because the object is always exchanging with the outside world, the state of the object is always in the direction of reducing the free energy. When the free energy is stable, the object reaches a balance state.

Cooling process: the thermal movement of molecules inside the object gradually weakens and tends to be orderly, and the energy of the object will drop, thus reaching a low-energy crystal shape.

Metropolis guidelines

In the simulated annealing algorithm, a very important criterion is called the Metropolis criterion. The process of this criterion is as follows:

1. First, set an initial condition, the initial number k, the initial temperature T, the solution (also known as the state) S(k) output in the process, give S(k) an initial value S(k)=S0;

2. ① generate an adjacent subset N(S(k)) on the state s of S(k) (current solution) in a certain way,
② In N(S(k)), a state s' is randomly selected as a candidate solution, and the difference between the candidate solution and the current solution is calculated to compare which one is better. ΔC’=C(S’)-C(S(k));

3. Next, we will discuss according to the situation of Δ C ':
① If Δ C '< 0, then S' is the best solution;
② If Δ C '> 0, then S' should be chosen as the optimal solution according to the formula with probability P=e^{-(Ej − Ei)/(k * T)}. Where Ej is the energy of the new state j, Ei is the energy of the old state i, K is the proportional coefficient of the temperature drop, and T is the current temperature.

4.k=k+1, the status is updated. Before the next operation, check whether the algorithm has met the termination conditions:
① If satisfied, proceed to step 5.
② If not, return to step 2 to continue.

5. At this time, the optimal solution S(k) obtained is the final answer, and the program ends.

simulated annealing

1.S(0)=S0 sets the initial state, i=0, and records the times of operation;

2. Set the initial temperature T=Ti, call the Metropolis sampling algorithm with T and S(k), and return the state Si as the current solution of the algorithm, at this time S=Si;

3. Cool down in a certain way, i.e. T=T(i+1), where t (I + 1) < Ti, i=i+1;

4. Check whether the termination condition is met. If it is, carry out step (5). Otherwise, carry out step (2).

5. The current Si is the optimal solution and the output stops.

TSP problem

TSP problem is also called traveling salesman problem (TSP). It was put forward by Irish mathematician Sir William Rowan Hamilton and British mathematician Thomas Penyngton Kirkman in the 19th century.

Its description is as follows: a businessman wants to go to several cities to sell goods, knowing the number of cities and the distance (or travel expenses) between cities, asking for a route starting from city 1, passing through all cities and each city can only be visited once, and finally returning to city 1, so as to minimize the total distance (or travel expenses). It has been proved to be a NP (non deterministic polynomial) problem.

Advantages of simulated annealing in solving TSP problems

The old algorithm has the following disadvantages in solving TSP: high time complexity, unknown time complexity in the worst case, will fall into the trap of local optimal solution.

SAA can accept the new solution according to the Metropolis criterion. In addition to the optimal solution, SAA can also accept the deteriorated solution within a certain limit. When the temperature T value is large, the acceptable deterioration solution is poor; when the temperature T value is small, the acceptable deterioration solution begins to get better. When T - > 0, we no longer accept the deteriorating solution.

Such an algorithm can jump out of the trap of local optimal solution. With the decrease of T, the probability of global optimal solution returned by the algorithm monotonically increases, and the probability of non optimal solution decreases.

Code

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include<fstream>
#include<typeinfo>
#include<vector>
#include <iterator>

#define N     200      //Maximum number of cities
#define T     3000    //initial temperature
#define ET   1e-8    //Termination temperature
#define DELTA 0.98    //Temperature decay rate
#define LIMIT 1000   //Upper limit of probability selection
#define OUTLOOP 20    //Number of external cycles
#define INLOOP 100   //Number of internal cycles

using namespace std;

//Defining the structure of an alignment
struct Path
{
    int city[N];//City node
    double len;//Length of route

};

//Define the structure of the city
struct City
{
    double w[N][N];//Record the distance between two cities
    double x, y;//Record the coordinates of the city
    int n;
};
Path b;//Best path
City p[N];//Record the coordinates of each city
City C;
int ncase;//Record the total number of tests

double dis(City A, City B)//Calculate the distance between points A and B
{
    return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));

}

void GetDist(City& C,City p[])//Store the distance between a and B cities
{
    for (int i = 0; i < C.n; i++)
        for (int j = i + 1; j < C.n; j++)
            C.w[i][j] = C.w[j][i] = dis(p[i], p[j]);
}

void Inputf(int& n,City p[])//Enter coordinates for each city
{
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> p[i].x >> p[i].y;
    }
    
}

void Input(int& n, City& C)
{
     C.n=n;

}

void tIn(int& n, City p[])
{
    int i, datalen = 0;
    double num[600];
    ifstream file("data.txt");
    while (!file.eof())
        file >> num[datalen++];
    n = num[0];
    for (int i = 1; i < datalen - 1; i++)
    {
        if (i % 2 == 0)
            p[i - 1].y = num[i];
        else
            p[i - 1].x = num[i];
    }
}
void Init(City C)//Create a path
{
    ncase = 0;
    b.len = 0;
    for (int i = 0; i < C.n; i++)
    {
        b.city[i] = i;
        if (i != C.n - 1)
        {
            cout << i <<"----->";//Print this city node
            b.len += C.w[i][i + 1];//Increase in the length of the best path
        }
        else
            cout << i<<endl;//Print last city node

    }
}

void Print(Path t, City C)//Print specific route and length
{
    cout << "Path is : ";
    for (int i = 0; i <= C.n; i++)
    {
        if (i != C.n)
            cout << t.city[i] << "-->";
        else
            cout << t.city[i];
    }
    cout << "\nThe path length is :\n" << t.len;
    cout << "-----------------------------------\n\n";
}

Path GetNext(Path p,City C)
{
    //Path p; 
    Path ans = p;
    int x = rand() % (C.n - 1) + 1;// %Remainder - > to control the random number at [1, n - 1]
    int y = rand() % (C.n - 1) + 1;
    while (x == y)//Ensure that x and y are not equal
    {
        x = rand() % (C.n - 1) + 1;
        y = rand() % (C.n - 1) + 1;
    }
    swap(ans.city[x], ans.city[y]);//A way to exchange the location of two cities
    ans.len = 0;
    for (int i = 0; i < C.n-1; i++)
        ans.len += C.w[ans.city[i]][ans.city[i + 1]];//Calculate the length of the route
    ans.len += C.w[ans.city[C.n - 1]][ans.city[0]];
    cout << "nCase = " << ncase << endl;//Printing has gone through several situations
    Print(ans, C);//Print route
    ncase++;
    return ans;
}

void SA(City C)
{
    double t = T;
    srand((unsigned)(time(NULL)));
    Path curPath = b;
    Path newPath = b;
    int P_L = 0;
    int P_F = 0;
    while (1)       //External circulation, main update parameter t, simulated annealing process
    {
        for (int i = 0; i < INLOOP; i++)    //Internal circulation, looking for the best value at a certain temperature
        {
            newPath = GetNext(curPath, C);//Randomly generate route
            double dE = newPath.len - curPath.len;//Calculate if the new route is better
            if (dE < 0)   //If the new route is better, update it directly
            {
                curPath = newPath;
                P_L = 0;
                P_F = 0;
            }
            else
            {
                double rd = rand() / (RAND_MAX + 1.0);//If the solution is not good, it will be updated with a certain probability, and the probability will be smaller and smaller
                if (exp(dE / t) > rd&& exp(dE / t) < 1)
                    curPath = newPath;
                P_L++;
            }
            if (P_L > LIMIT)//If the probability of more than a thousand choices
            {
                P_F++;//End of primary external circulation
                break;
            }
        }
        if (curPath.len < b.len)
            b = curPath;//Update if the current path is optimal
        if (P_F > OUTLOOP || t < ET)//If the external cycle exceeds 20 times and the temperature drops to the end temperature, the cycle will jump out
            break;
        t *= DELTA;//Otherwise, the temperature will decay at a rate of 0.98
    }
}

int main(int argc, const char* argv[]) {
    int n;
    tIn(n, p);
    Input(n,C);
    GetDist(C,p);
    Init(C);
    SA(C);
    Print(b, C);
    cout << "Total test times is \n" << ncase;
    return 0;
}

Program screenshots

data.txt text

This text is placed in the folder where the program is located. At first, the program uses manual input, and then manual input has small amount of data, low efficiency and other reasons, and finally uses text reading.

The first line is the total number of cities
Here are the coordinates of each city

Run screenshots

All the test results are printed out, and the last result is the optimal path graph.


Thank you here.
https://blog.csdn.net/baimafujinji/article/details/52573630
and
https://blog.csdn.net/qq_34062105/article/details/80468038?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
The guidance of the maze.

Published 6 original articles, won praise 4, visited 435
Private letter follow