Introduction to Artificial Intelligence——Genetic Algorithm Solving TSP Problem Experiment

1. Purpose of the experiment:

Familiar with and master the principle, process and coding strategy of genetic algorithm, and use genetic algorithm to solve combinatorial optimization problems, understand the process of solving TSP problems and test the influence of main parameters on the results.

2. Experimental principle:

The traveling salesman problem, TSP problem (Traveling Salesman Problem) is one of the famous problems in the field of mathematics. Assuming that a traveling businessman wants to visit n cities, he must choose the path he wants to take. The limit of the route is that each city can only be visited once, and finally he must return to the original city from which he started. The goal of path selection is that the required path distance is the minimum value among all paths. The TSP problem is a combinatorial optimization problem. The problem can be shown to have NPC computational complexity. Therefore, any method that can simplify the solution of this problem will be highly evaluated and paid attention to.

The basic principle of the genetic algorithm is to solve the problem by acting on the genes on the chromosome to find a good chromosome. It needs to evaluate each chromosome generated by the algorithm, and select the chromosome based on the fitness value, so that the chromosome with good adaptability has More breeding opportunities. In the genetic algorithm, a number of digital codes of the problem to be solved are randomly generated, that is, chromosomes, to form the initial population; each individual is given a numerical evaluation through the fitness function, and individuals with low fitness are eliminated. Individuals with high fitness are selected to participate in the genetic operation, and the collection of individuals after the inheritance operation forms a new population of the next generation, and the next round of evolution is carried out on this new population. This experiment requires the use of genetic algorithm to solve the shortest path of the TSP problem.

3. Experimental content:

1. Refer to the core code of the genetic algorithm given by the experimental system. It is required to use the genetic algorithm to solve different scales (such as 10 cities, 30 cities, and 100 cities) under the same population size, maximum number of iteration steps, and number of independent operations. Fill in the results in Table 1 for the TSP problem.

Table 1 The results of genetic algorithm for solving TSP problems of different scales

city ​​size

population size

Maximum number of iterations

number of independent runs

best fitness

worst fitness

average fitness

average running time

10

100

100

10

25.1652

25.8521

25.3501

47 p

30

100

100

10

10605.7

11868

11281.2

122.8s

100

100

100

10

44334.9

47149.1

46117.6

484.2s

  1. Set the population size to 100, the crossover probability to 0.8, and the mutation probability to 0.8, and then add a mutation strategy (such as two adjacent points exchange mutation, reverse mutation or insertion mutation, etc.) and an individual selection probability allocation strategy (such as by Linear sorting or assigning individual selection probabilities according to nonlinear sorting) is used to solve the TSP problem of 30 cities (the coordinates of the 30 cities are as follows), and the results are filled in Table 2.

30 city coordinates:

x[0]=41, x[1]=37,x[2]=54,x[3]=25,x[4]=7,x[5]=2,x[6]=68,x[7]=71,x[8]=54,x[9]=83;

y[0]=94,y[1]=84,y[2]=67,y[3]=62,y[4]=64,y[5]=99,y[6]=58,y [7]=44,y[8]=62,y[9]=69;

x[10]=64,x[11]=18,x[12]=22,x[13]=83,x[14]=91,x[15]=25,x[16]=24,x[17]=58,x[18]=71,x[19]=74;

y[10]=60,y[11]=54,y[12]=60,y[13]=46,y[14]=38,y[15]=38,y[16]=42,y [17]=69,y[18]=71,y[19]=78;

x[20]=87,x[21]=18,x[22]=13,x[23]=82,x[24]=62,x[25]=58,x[26]=45,x[27]=41,x[28]=44, x[29]=4;

y[20]=76,y[21]=40,y[22]=40,y[23]=7,y[24]=32,y[25]=35,y[26]=21,y [27]=26,and[28]=35; y[29]=50;

Table 2 The solution results of different mutation strategies and individual selection probability assignment strategies

mutation strategy

individual choice probability assignment

Maximum number of iterations

number of independent runs

best fitness

worst fitness

average fitness

average running time

two point swap

Proportional distribution according to fitness

100

10

889.434

982.154

938.503

59s

two point swap

Sort linearly

100

10

488.833

567.304

513.735

51s

Swap two adjacent points

Sort linearly

100

10

1022.77

1104.54

1064.78

49.1s

Swap two adjacent points

Proportional distribution according to fitness

100

10

878.549

969.802

939.414

58s

3. Given the data of 34 provincial capitals in China, it is required to design an improved genetic algorithm based on this data to solve the TSP problem. It is required to give 1) the improved algorithm strategy and core code, 2) the main parameter settings of the improved algorithm (population size, crossover probability, mutation probability, maximum number of iteration steps, etc.), 3) the shortest distance between the 34 provincial capitals finally obtained by the improved algorithm Path value, optimal individual and algorithm running time, 4) Given the same parameter settings (population size, crossover probability, mutation probability, maximum number of iteration steps, etc.), using the basic genetic algorithm (without using the improved strategy) to obtain The shortest path value, optimal individual and algorithm running time of the 34 provincial capitals.

Figure 1 Location of 34 provincial capitals in China (1295.72)

Table 3 34 provincial capital cities and pixel coordinate table

City

Tibet

Yunnan

sichuan

Qinghai

Ningxia

Gansu

Inner Mongolia

Heilongjiang

Jilin

liaoning

Beijing

Tianjin

city ​​number

1

2

3

4

5

6

7

8

9

10

11

12

X coordinate

100

187

201

187

221

202

258

352

346

336

290

297

Y coordinate

211

265

214

158

142

165

121

66

85

106

127

135

City

Hebei

Shandong

Henan

Shanxi

Shaanxi

Anhui

Jiangsu

Shanghai

zhejiang

Jiangxi

Hubei

Hunan

city ​​number

13

14

15

16

17

18

19

20

21

22

23

24

X coordinate

278

296

274

265

239

302

316

334

325

293

280

271

Y coordinate

147

158

177

148

182

203

199

206

215

233

216

238

City

Guizhou

Guangxi

Guangdong

Fujian

Hainan

Macao

Hongkong

Taiwan

chongqing

Xinjiang

city ​​number

25

26

27

28

29

30

31

32

33

34

X coordinate

221

233

275

322

250

277

286

342

220

104

Y coordinate

253

287

285

254

315

293

290

263

226

77

x[0]=100, x[1]=187,x[2]=201,x[3]=187,x[4]=221,x[5]=202,x[6]=258,x[7]=352,x[8]=346,x[9]=336;

y[0]=211,y[1]=265,y[2]=214,y[3]=158,y[4]=142,y[5]=165,y[6]=121,y [7]=66,y[8]=85,y[9]=106;

x[10]=290,x[11]=297,x[12]=278,x[13]=296,x[14]=274,x[15]=265,x[16]=239,x[17]=302,x[18]=316,x[19]=334;

y[10]=127,y[11]=135,y[12]=147,y[13]=158,y[14]=177,y[15]=148,y[16]=182,y [17]=203,y[18]=199,y[19]=206;

x[20]=325,x[21]=293,x[22]=280,x[23]=271,x[24]=221,x[25]=233,x[26]=275,x[27]=322,x[28]=250, x[29]=277;

y[20]=215,y[21]=233,y[22]=216,y[23]=238,y[24]=253,y[25]=287,y[26]=285,y [27]=254,and[28]=315; y[29]=293;

x[30]=286, x[31]=342,x[32]=220,x[33]=104;

y[30]=290,y[31]=263,y[32]=226,y[33]=77;

3.1 Results:

3.1.1 Here are two experimental results, the difference is only the initial starting point is different

① Draw the path as shown in Figure 2 (based on python, starting point 15):

Fig. 2 Plot showing the optimal solution

Shortest path length 1532.3994414550848

Path representation: [23, 32, 24, 1, 2, 0, 33, 3, 5, 4, 12, 14, 16, 22, 21, 27, 31, 30, 26, 29, 28, 25, 20, 19, 18, 17, 13, 11, 9, 8, 7, 10, 6]

The path length decreases with the number of iterations:

Figure 3 The relationship between the number of iterations and the optimal solution

② Draw the path as shown in the figure (based on python, starting point 32):

Figure 4 is a plot showing the optimal solution

Shortest path length: 1551.0699954694958

Path representation: [1, 28, 25, 24, 18, 20, 19, 31, 27, 29, 30, 26, 23, 21, 22, 16, 14, 17, 13, 9, 8, 7, 11, 10, 12, 15, 6, 4, 5, 0, 33, 3, 2]

The path length decreases with the number of iterations:

Figure 5 The relationship between the optimal solution and the number of iterations

3.1.2

If not improved, use the original program, and the parameters are set as follows (based on C++):

Chromosome length: 34

Maximum iteration steps: 500

Population size: 100

Crossover Probability: 0.5

Mutation probability 0.15

Selection operation: distribute the selection probability of individuals according to the fitness ratio, and select individuals by roulette

Crossover Operation: PMX Crossover

Mutation operation: swap two adjacent points

The result is shown in Figure 6:

Figure 6 Results

The optimal path length is: 6246.62

Path: 32-20-18-21-28-29-26-24-13-30-12-10-31-33-2-3-1-7-9-4-15-11-0-5- 8-6-17-16-23-25-19-22-27-14

The running time is: 214.6s

It can be seen that the improved algorithm is quite effective.

3.2 Improved algorithm strategy and core code :

①Parameter setting:
#population number

count=300

#Improve times

improve_count=10000

#Evolution times

itter_time=3000

#Set the definition probability of the strong, that is, the top 30% of the population are the strong

retain_rate=0.3

#Set the survival probability of the weak

random_select_rate=0.5

#mutation rate

mutation_rate=0.1

②Path coding:

Number the cities 0, 1, 2, 3...33, chromosome {x1, x2, x3...x33}, which means starting from x1, going through x2, x3....x33 and then returning to x1 , the starting point can be set arbitrarily, in this program it is set to 15.

③ Initialize the population:

In order to speed up the running speed of the program, some better individuals should be selected in the selection of the initial population. First use the classical approximation algorithm—improved circle algorithm to obtain a better initial population. The idea of ​​the algorithm is to randomly generate a chromosome, such as {1, 2, ... 33}, exchange the sequential positions of the two cities arbitrarily, if the total distance decreases, update and change the chromosome, and repeat until no further modification can be made.

code:

#Initialize population

population = []

for i in range(count):

    # Randomly generate individuals

    x = index.copy()

    random.shuffle(x)

    improve(x)

    population.append(x)

# improvement

def improve(x):

    i=0

    distance=get_total_distance(x)

    while i<improve_count:

        # randint [a,b]

        u=random.randint(0,len(x)-1)

        v = random.randint(0, len(x)-1)

        if u!=v:

            new_x=x.copy()

            t=new_x[u]

            new_x[u]=new_x[v]

            new_x[v]=t

            new_distance=get_total_distance(new_x)

            if new_distance<distance:

                distance=new_distance

                x=new_x.copy()

        else:

            continue

        i+=1

④Select strategy:

Although the roulette wheel method is the most used selection strategy, this strategy may produce large sampling errors. Therefore, this uses natural selection to calculate the distance between each city and store it in the matrix. The total distance Sort from small to large, select the chromosomes with strong adaptability, and then select the chromosomes with less adaptability but surviving chromosomes (random selection).

Core code:

# natural selection

def selection(population):

    # Sort the total distance from small to large

    graded = [[get_total_distance(x), x] for x in population]

    graded = [x[1] for x in sorted(graded)]

    # Select the most adaptive chromosomes

    retain_length = int(len(graded) * retain_rate)

    parents = graded[:retain_length]

    # Select less adaptive but surviving chromosomes

    for chromosome in graded[retain_length:]:

        if random.random() < random_select_rate:

            parents.append(chromosome)

    return parents

⑤ Variation strategy:

According to the given mutation rate, randomly select three integers for the selected mutated individuals, satisfying 1<u<v<w<33, and insert the gene segment between v and u (including u and v) into w later. Replace the original two adjacent point swap mutation, and the mutation strategy of two point swap. 

Core code:

#Mutations

def mutation(children):

    for i in range(len(children)):

        if random.random() < mutation_rate:

            child=children[i]

            u=random.randint(1,len(child)-4)

            v = random.randint(u+1, len(child)-3)

            w= random.randint(v+1, len(child)-2)

            child=children[i]

            child=child[0:u]+child[v:w]+child[u:v]+child[w:]

4. Submit the experiment report and source program.

3. Experimental results :

Experimental content 1 result:

Table 1 The results of genetic algorithm for solving TSP problems of different scales

city ​​size

population size

Maximum number of iterations

number of independent runs

best fitness

worst fitness

average fitness

average running time

10

100

100

10

25.1652

25.8521

25.3501

47 p

30

100

100

10

10605.7

11868

11281.2

122.8s

100

100

100

10

44334.9

47149.1

46117.6

484.2s

Experimental content 2 results:

Table 2 The solution results of different mutation strategies and individual selection probability assignment strategies

mutation strategy

individual choice probability assignment

Maximum number of iterations

number of independent runs

best fitness

worst fitness

average fitness

average running time

two point swap

Proportional distribution according to fitness

100

10

889.434

982.154

938.503

59s

two point swap

Sort linearly

100

10

488.833

567.304

513.735

51s

Swap two adjacent points

Sort linearly

100

10

1022.77

1104.54

1064.78

49.1s

Swap two adjacent points

Proportional distribution according to fitness

100

10

878.549

969.802

939.414

58s

The result of experiment content 3, located in experiment content 3:

The path is shown in Figure 2:

Shortest path length 1532.3994414550848

Path representation: [23, 32, 24, 1, 2, 0, 33, 3, 5, 4, 12, 14, 16, 22, 21, 27, 31, 30, 26, 29, 28, 25, 20, 19, 18, 17, 13, 11, 9, 8, 7, 10, 6]

4. Experimental thinking and experience :

  1. Analyze the algorithm performance of genetic algorithm for solving TSP problems of different scales.

The larger the city size, the larger the number of iterations, the longer the search for the optimal solution, and the longer the waiting time for the result.

2. Add 1 mutation strategy and 1 individual selection probability distribution strategy, and compare the influence of different mutation strategies and individual selection distribution strategies on the algorithm results when solving TSP problems in 30 cities.

Added adjacent two-point mutation and linear sorting to select individuals:

Mutation strategy:

void change1(vector<int>& K, int N){//mutation strategy: exchange mutation between two adjacent points

int i = next_int() % N;

swap(K[i], K[(i + 1) % N]);

}

Individual selection strategy:

if(make_p==1)//linear sort

    {

        for(int i=0;i<popsize;i++)

ps[i]=(200-2*i)/popsize*(popsize+1);

}

From the experimental results, the linear sorting is better, and the random two-point exchange strategy is obviously better than the adjacent two-point exchange strategy.

3. Comparatively analyze the influence of the improved strategy of the genetic algorithm on the results of solving the TSP problems of 34 cities.

The main reason is that a relatively large improvement has been made in the selection of the fitness value. The better individuals are selected first, and some poor individuals are randomly selected. By improving the code of some parameters, selection and mutation, you can make what you want to get The optimal solution of is better. If the improvement is not used, the optimal solution that can be obtained in the final operation is about 7.8 thousand, as shown in Figure 7, and the accuracy is far from enough.

 

Figure 7 Unimproved running results

4. Summarize the experience of the experiment:

There are many other improvement strategies, such as:

①Using the greedy algorithm to initialize the population, the basic idea of ​​each individual generation is: first randomly select the city ccurrent from n cities as the first gene, and then find the city cnext (cnext) from the remaining n-1 cities cnext is the city closest to ccurrent) as the second gene, and then find the city cnext+1 from the remaining n-2 cities (cnext+1 is the city closest to cnext) as the third gene, and so on until Traverse n cities so far. The proportion of some populations generated by the greedy algorithm is not large. While improving the overall quality of the initial population, it will not affect the diversity of the initial population, which helps to speed up the optimization speed. Because I am not very familiar with the code, I failed to change it to a greedy algorithm to initialize the population.

② It is also possible to appropriately enlarge the fitness and consider the fractional part, but from the results of the experimental run, it is not very meaningful. The optimal solution is relatively average, and the distance is still quite large.

③Improved crossover operator: the two-point crossover operator commonly used in basic genetic algorithms. This crossover method only crosses the genes between the two points of the parent individual. The genes outside the two points are either unchanged or blind due to node duplication. The good genes of the parent cannot be effectively inherited. Two-point three-segment random crossover can be used.

Unimproved source code:

#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#include<ctime>
#include<time.h>
using namespace std;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define PB push_back
#define MP make_pair

int next_int()
{
	return rand()*(RAND_MAX+1)+rand();
}
double next_double()
{
	return (double(rand()*(RAND_MAX+1)+rand()))/((RAND_MAX+1)*RAND_MAX+RAND_MAX);
}
void pmx(VI& a,VI& b,int pointcnt)//PMX交叉
{
	int sa=next_int()%pointcnt,sb=next_int()%pointcnt;//随机选择两交叉位
	int temp;
	if (sa>sb)
	{
		temp=sa;
		sa=sb;
		sb=temp;
	}//保证交叉位sa<=sb
	VI aa(pointcnt),bb(pointcnt);
	int i;	
	for(i=0;i<pointcnt;i++)
	{
		aa[i]=a[i],bb[i]=b[i];	
	}
	VI m1(pointcnt,-1);
	VI m2(pointcnt,-1);	
	VI v1tov2(pointcnt,-1);
	for(i=sa;i<=sb;i++)
	{   
		m1[aa[i]]=-2;	//m1存放aa非交叉段可代换的基因
		m2[bb[i]]=-2;	//m2存放aa非交叉段可代换的基因
	}	
	for(i=0;i<pointcnt;i++)	{   
		
		if(m2[i]==m1[i])//去掉m1和m2中重复代换的基因
		{
			m2[i]=-1;
			m1[i]=-1;
		}
	}
	int aaa=0;
	for(i=sa;i<=sb;i++)
	{
		if ((m1[aa[i]]==-2)&&(m2[bb[i]]==-2))
		{
			v1tov2[aa[i]]=bb[i];//v1tov2存放首先可以确定的互换基因
			m1[aa[i]]=-1;
			m2[bb[i]]=-1;
			aaa++;			
		}
	}
	if(aaa!=(sb-sa+1))
	{
		for(i=0;i<pointcnt;i++)	
			if (m1[i]==-2) 
			{
				int aflag=0;
				for(int j=0;j<pointcnt;j++)	
					if( (m2[j]==-2) && (aflag==0))//寻找并确定可以互换的基因
					{
						v1tov2[i]=j; 
						aflag=1;
						aaa++;
						m2[j]=-1;
						m1[i]=-1;					
					}
			}

	}
	for(i=sa;i<=sb;i++)	{	
	
		swap(aa[i],bb[i]);	//交换sa到sb之间的基因串
	}

	for(i=0;i<pointcnt;i++)//查找染色体aa中sa之前和sb之后的基因是否有重复
	{   
		if ((i<sa)||(i>sb))
			for (int j=sa;j<=sb;j++)
			{
				if(aa[i]==aa[j])  //有重复基因
				{  
					for(int k=0;k<pointcnt;k++)
						if(aa[i]==v1tov2[k])  
							aa[i]=k;	//进行互换			
				
				}
			}
		
	}
		
	for(i=0;i<pointcnt;i++)//查找染色体bb中sa之前和sb之后的基因是否有重复
	{  
		if ((i<sa)||(i>sb))
			for (int j=sa;j<=sb;j++)
			{	
				if(bb[i]==bb[j]) //有重复基因			
					bb[i]=v1tov2[bb[i]];	//进行互换				
			}
	
	}
	a=aa;
	b=bb;
	
}

vector<double> x,y;
double fitness(const VI& v,int pointcnt)//计算适应度
{
	double r=0;
	for(int i=0;i<pointcnt;i++)
	{
		double dx=x[v[i]]-x[v[(i+1)%pointcnt]];
		double dy=y[v[i]]-y[v[(i+1)%pointcnt]];
		r+=sqrt(dx*dx+dy*dy);//个体的适应度为相邻两城市之间的距离平方的平方根和
	}
	return 1.0/r;
}
void change0(vector<int>& K,int N)//变异策略:两点互换
{
	int i=next_int()%N;
	int d=next_int()%(N-1);
	int j=(i+1+d)%N;
	swap(K[i],K[j]);
}


void change1(vector<int>& K, int N){//变异策略:相邻两点互换变异 
	int i = next_int() % N;
	swap(K[i], K[(i + 1) % N]);	
}



void mutate(VI& route,int mutate_type,int pointcnt)
{
	
	if(mutate_type==0)//两点互换
		change0(route,pointcnt);	
	if(mutate_type==1)//相邻两点互换变异 
	    change1(route,pointcnt);
}



bool pair_dec(const pair<double,VI*>& a,const pair<double,VI*>& b)
{
	return a>b;
}

class other_population
{
public:
	int popsize,pointcnt;//种群规模,染色体长度
	double pc,pm;//交叉概率,变异概率
	vector<pair<double,VI*> >pop;//种群
	pair<double,VI*> bestofpop;//最好个体
	int cross_type;//交叉类型
	int mutate_type;//变异类型
	int make_p;//个体概率分配策略类型
	int select_type;//个体选择类型
	int toursize;//竞赛规模
	double bestp;//最好个体选择概率
	other_population(int a,int b,int c,int f,int g,double d,double e,int h,double j,int m)
	{
		popsize=a,pointcnt=b,cross_type=c,mutate_type=f,make_p=g,pc=d,pm=e,toursize=h,bestp=j,select_type=m;
		for(int i=0;i<popsize;i++)//初始化种群
		{
			VI* v=new VI(pointcnt);
			for(int j=0;j<pointcnt;j++)
				(*v)[j]=j;
			random_shuffle(v->begin(),v->end());
			pop.PB(MP(fitness(*v,pointcnt),v));
		}
		sort(pop.begin(),pop.end(),pair_dec);
		bestofpop.first=pop[0].first;//初始时最好个体的适应度
		bestofpop.second=new VI(*pop[0].second);//初始时最好个体的染色体
	}
	~other_population()
	{
		for(int i=0;unsigned(i)<pop.size();i++)
			delete pop[i].second;
		delete bestofpop.second;
	}
	void next()//产生下一代种群
	{
		vector<double> ps(popsize);
		if(make_p==0) //按适应度比例分配个体的选择概率
		{
			double sum=0;
			for(int i=0;i<popsize;i++)
				sum+=pop[i].first;//计算种群的适应度和
			for(int i=0;i<popsize;i++)
				ps[i]=pop[i].first/sum;
		}	
		
		
		if(make_p==1)//线性排序 
	    {
	        for(int i=0;i<popsize;i++)
			ps[i]=(200-2*i)/popsize*(popsize+1);	
		}
	
		if(select_type==0)//轮盘赌选择个体
		{
			vector<pair<double,VI*> > select_res;
			vector<double> addsum(popsize);
			for(int i=0;i<popsize-1;i++)//计算个体的累计概率
			{
				if(i==0)
					addsum[i]=ps[0];
				else
					addsum[i]=addsum[i-1]+ps[i];
			}
			addsum[popsize-1]=1;//1.5;
			for(int i=0;i<popsize;i++)
			{
				double rd=next_double();
				int r=lower_bound(addsum.begin(),addsum.end(),rd)-addsum.begin();
				VI* v=new VI(*pop[r].second);
				select_res.PB(MP(fitness(*v,pointcnt),v));
			}
			for(int i=0;i<popsize;i++)
				delete pop[i].second;
			pop=select_res;
		}		
		for(int cc=0;cc<popsize/2;cc++)//随机选择两个个体,然后进行交叉
		{
			int a=next_int()%popsize;
			int b=(a+1+(next_int()%(popsize-1)))%popsize;
			if(next_double()<pc)//随机数小于交叉概率,进行交叉
			{
				if(cross_type==0)//pmx交叉
					pmx(*pop[a].second,*pop[b].second,pointcnt);
			
				pop[a].first=fitness(*pop[a].second,pointcnt);//计算交叉后个体a的适应度
				if(bestofpop.first<pop[a].first)//更新最好个体
				{
					bestofpop.first=pop[a].first;
					delete bestofpop.second;
					bestofpop.second=new VI(*pop[a].second);
				}
				pop[b].first=fitness(*pop[b].second,pointcnt);//计算交叉后个体b的适应度
				if(bestofpop.first<pop[b].first)//更新最好个体
				{
					bestofpop.first=pop[b].first;
					delete bestofpop.second;
					bestofpop.second=new VI(*pop[b].second);
				}
			}
		}
		for(int i=pop.size()-1;i>=0;i--)//进行变异
			if(next_double()<pm)//随机数小于变异概率,进行变异
			{
				mutate(*pop[i].second,mutate_type,pointcnt);//变异
				pop[i].first=fitness(*pop[i].second,pointcnt);//计算变异后个体的适应度
			}
		sort(pop.begin(),pop.end(),pair_dec);//从大到小排序
		if(bestofpop.first<pop[0].first)//更新最好个体
		{
			delete bestofpop.second;
			bestofpop.first=pop[0].first;
			bestofpop.second=new VI(*pop[0].second);
		}
	}
};

int main()
{
	srand((unsigned)time(NULL));
	int CASNUM,POINTCNT,POPSIZE,GENERATIONS;
	//scanf("%d",&CASNUM);//输入实验次数
	CASNUM=10;//输入实验次数
	cout << "实验次数:" << CASNUM << "次" << endl;
	//scanf("%d%d%d",&POINTCNT,&POPSIZE,&GENERATIONS);//输入染色体长度(城市数),种群规模,最大迭代步数
	POINTCNT=30;//输入染色体长度(城市数)
	POPSIZE=100,GENERATIONS=100;//输入种群规模,最大迭代步数
	x.resize(POINTCNT);
	y.resize(POINTCNT);
//	x[0]=0, x[1]=1.1,x[2]=3.5,x[3]=3,x[4]=7,x[5]=8,x[6]=4,x[7]=4.5,x[8]=9,x[9]=2;
	//x[10]=10, x[11]=11.1,x[12]=13.5,x[13]=13,x[14]=17,x[15]=18,x[16]=14,x[17]=14.5,x[18]=19,x[19]=12;
//	y[0]=1.1,y[1]=3,y[2]=2,y[3]=4,y[4]=5.1,y[5]=8,y[6]=4,y[7]=4.5,y[8]=9,y[9]=2;
	//y[10]=11.1,y[11]=13,y[12]=12,y[13]=14,y[14]=15.1,y[15]=18,y[16]=14,y[17]=14.5,y[18]=19,y[19]=12;
	
x[0]=41, x[1]=37,x[2]=54,x[3]=25,x[4]=7,x[5]=2,x[6]=68,x[7]=71,x[8]=54,x[9]=83;
y[0]=94,y[1]=84,y[2]=67,y[3]=62,y[4]=64,y[5]=99,y[6]=58,y[7]=44,y[8]=62,y[9]=69;
x[10]=64,x[11]=18,x[12]=22,x[13]=83,x[14]=91,x[15]=25,x[16]=24,x[17]=58,x[18]=71,x[19]=74;
y[10]=60,y[11]=54,y[12]=60,y[13]=46,y[14]=38,y[15]=38,y[16]=42,y[17]=69,y[18]=71,y[19]=78;
x[20]=87,x[21]=18,x[22]=13,x[23]=82,x[24]=62,x[25]=58,x[26]=45,x[27]=41,x[28]=44, x[29]=4;
y[20]=76,y[21]=40,y[22]=40,y[23]=7,y[24]=32,y[25]=35,y[26]=21,y[27]=26,y[28]=35; y[29]=50;

	
	cout<<"城市数="<<POINTCNT<<endl;
	cout<<"各城市坐标:"<<endl;
	//srand((unsigned)time(NULL));
/*	for(int i=10;i<POINTCNT;i++)
	{
		x[i]=next_int()%1000;y[i]=next_int()%1000;
	}*/
	for(int i=0;i<POINTCNT;i++)
	{
		//scanf("%lf%lf",&x[i],&y[i]);//输入各个城市的坐标		
		cout<<"["<<x[i]<<", "<<y[i]<<"]"<<endl;//输出各个城市的坐标				
	}
	cout<<"染色体长度:"<<POINTCNT<<endl;
	cout<<"最大迭代步数:"<<GENERATIONS<<endl;
	cout<<"种群规模:"<<POPSIZE<<endl;
	int select_type,make_p_type,k,cross_type,mutate_type;
	double q,pc,pm;
	
	select_type=0,make_p_type=1,k=5;//输入个体选择方法类型,个体选择概率分配类型,竞赛规模
	q=0.5,pc=0.8,pm=0.8;//输入最好个体选择概率,交叉概率,变异概率
	cross_type=0,mutate_type=0;//输入交叉类型,变异类型
	
	
	cout<<"交叉概率:"<<pc<<endl;
	cout<<"变异概率"<<pm<<endl;
	cout<<"选择操作:按适应度比例分配个体的选择概率,轮盘赌选择个体"<<endl;
	cout<<"交叉操作:PMX交叉"<<endl;
	cout<<"变异操作:两点互换"<<endl;
	double best=1e9,worst=0,sum=0;
	VI res;
	clock_t start_time;
	start_time=clock();
	cout << endl;
	cout << "正在计算中......" << endl;
	for(int cas=0;cas<CASNUM;cas++)//
	{
		other_population gen(POPSIZE,POINTCNT,cross_type,mutate_type,make_p_type,pc,pm,k,q,select_type);
	
		for(int g=0;g<GENERATIONS;g++)//进行迭代进化
			gen.next();
		if(best>1.0/gen.bestofpop.first)//更新最好适应度
		{
			best=1.0/gen.bestofpop.first;
			res=*gen.bestofpop.second;//存放最好个体的染色体
		}
		if(worst<1.0/gen.bestofpop.first)//更新最差适应度
			worst=1.0/gen.bestofpop.first;
		sum+=1.0/gen.bestofpop.first;//计算各次最好个体的适应度之和
	}
	cout << endl; 
	cout << CASNUM << "次遗传算法求解的结果如下:" << endl;
	clock_t	end_time=clock();
	double durTime=double(end_time-start_time);	
	sum/=CASNUM;//计算平均适应度
	cout<<"最好适应度:"<<best<<"\n"<<"最差适应度:"<<worst<<"\n"<<"平均适应度:"<<sum<<"\n";
	cout<<"输出最好解:";
	for(int i=0;i<POINTCNT;i++)//输出解
	{
		cout<<res[i];//输出各城市
		if (i<POINTCNT-1)
			cout<<"-";
	}
	cout<<endl;
	cout<<"平均运行时间:"<<durTime/CASNUM<<"s"<<endl;
	cout<<endl;

	return 0;
}

Guess you like

Origin blog.csdn.net/cangzhexingxing/article/details/124015579