TSP问题求解实验报告
实验六:遗传算法求解TSP问题实验2篇
实验六:遗传算法求解TSP问题实验2篇第一篇:遗传算法的原理与实现1. 引言旅行商问题(TSP问题)是一个典型的组合优化问题,它要求在给定一组城市和每对城市之间的距离后,找到一条路径,使得旅行商能够在所有城市中恰好访问一次并回到起点,并且总旅行距离最短。
遗传算法作为一种生物启发式算法,在解决TSP问题中具有一定的优势。
本实验将运用遗传算法求解TSP问题,以此来探讨和研究遗传算法在优化问题上的应用。
2. 遗传算法的基本原理遗传算法是模拟自然界生物进化过程的一种优化算法。
其基本原理可以概括为:选择、交叉和变异。
(1)选择:根据问题的目标函数,以适应度函数来评估个体的优劣程度,并按照适应度值进行选择,优秀的个体被保留下来用于下一代。
(2)交叉:从选出的个体中随机选择两个个体,进行基因的交换,以产生新的个体。
交叉算子的选择及实现方式会对算法效果产生很大的影响。
(3)变异:对新生成的个体进行基因的变异操作,以保证算法的搜索能够足够广泛、全面。
通过选择、交叉和变异操作,不断迭代生成新一代的个体,遗传算法能够逐步优化解,并最终找到问题的全局最优解。
3. 实验设计与实施(1)问题定义:给定一组城市和每对城市之间的距离数据,要求找到一条路径,访问所有城市一次并回到起点,使得旅行距离最短。
(2)数据集准备:选择适当规模的城市数据集,包括城市坐标和每对城市之间的距离,用于验证遗传算法的性能。
(3)遗传算法的实现:根据遗传算法的基本原理,设计相应的选择、交叉和变异操作,确定适应度函数的定义,以及选择和优化参数的设置。
(4)实验流程:a. 初始化种群:随机生成初始种群,每个个体表示一种解(路径)。
b. 计算适应度:根据适应度函数,计算每个个体的适应度值。
c. 选择操作:根据适应度值选择一定数量的个体,作为下一代的父代。
d. 交叉操作:对父代进行交叉操作,生成新的个体。
e. 变异操作:对新生成的个体进行变异操作,以增加搜索的多样性。
基于蚁群优化算法的TSP问题求解计算智能实验报告
智能计算实验报告学院:班级:学号:姓名:成绩:日期:实验名称:基于蚁群优化算法的TSP问题求解题目要求:利用蚁群优化算法对给定的TSP问题进行求解,求出一条最短路径。
蚁群优化算法简介:蚁群算法是一中求解复杂优化问题的启发式算法,该方法通过模拟蚁群对“信息素”的控制和利用进行搜索食物的过程,达到求解最优结果的目的。
它具有智能搜索、全局优化、稳健性强、易于其它方法结合等优点,适应于解决组合优化问题,包括运输路径优化问题。
TSP数据文件格式分析:本次课程设计采用的TSP文件是att48.tsp ,文件是由48组城市坐标构成的,文件共分成三列,第一列为城市编号,第二列为城市横坐标,第三列为城市纵坐标。
数据结构如下所示:实验操作过程:1、TSP文件的读取:class chengshi {int no;double x;double y;chengshi(int no, double x, double y) {this.no = no;this.x = x;this.y = y;}private double getDistance(chengshi chengshi) {return sqrt(pow((x - chengshi.x), 2) + pow((y - chengshi.y), 2));}}try {//定义HashMap保存读取的坐标信息HashMap<Integer, chengshi> map = new HashMap<Integer,chengshi>();//读取文件BufferedReader reader = new BufferedReader(new (new )));for (String str = reader.readLine(); str != null; str = reader.readLine()) { //将读到的信息保存入HashMapif(str.matches("([0-9]+)(\\s*)([0-9]+)(.?)([0-9]*)(\\s*)([0-9]+)(.?)([0-9]*)")) {String[] data = str.split("(\\s+)");chengshi chengshi = new chengshi(Integer.parseInt(data[0]),Double.parseDouble(data[1]),Double.parseDouble(data[2]));map.put(chengshi.no, chengshi);}}//分配距离矩阵存储空间distance = new double[map.size() + 1][map.size() + 1];//分配距离倒数矩阵存储空间heuristic = new double[map.size() + 1][map.size() + 1];//分配信息素矩阵存储空间pheromone = new double[map.size() + 1][map.size() + 1];for (int i = 1; i < map.size() + 1; i++) {for (int j = 1; j < map.size() + 1; j++) {//计算城市间的距离,并存入距离矩阵distance[i][j] = map.get(i).getDistance(map.get(j));//计算距离倒数,并存入距离倒数矩阵heuristic[i][j] = 1 / distance[i][j];//初始化信息素矩阵pheromone[i][j] = 1;}}} catch (Exception exception) {System.out.println("初始化数据失败!");}}2、TSP作图处理:private void evaporatePheromone() {for (int i = 1; i < pheromone.length; i++)for (int j = 1; j < pheromone.length; j++) {pheromone[i][j] *= 1-rate;}}3、关键源代码(带简单的注释):蚂蚁类代码:class mayi {//已访问城市列表private boolean[] visited;//访问顺序表private int[] tour;//已访问城市的个数private int n;//总的距离private double total;mayi() {//给访问顺序表分配空间tour = new int[distance.length+1];//已存入城市数量为n,刚开始为0n = 0;//将起始城市1,放入访问结点顺序表第一项tour[++n] = 1;//给已访问城市结点分配空间visited = new boolean[distance.length];//第一个城市为出发城市,设置为已访问visited[tour[n]] = true;}private int choosechengshi() {//用来random的随机数double m = 0;//获得当前所在的城市号放入j,如果和j相邻的城市没有被访问,那么加入mfor (int i = 1, j = tour[n]; i < pheromone.length; i++) {if (!visited[i]) {m += pow(pheromone[j][i], alpha) * pow(heuristic[j][i], beta);}}//保存随机数double p = m * random();//寻找随机城市double k = 0;//保存城市int q = 0;for (int i = 1, j = tour[n]; k < p; i++) {if (!visited[i]) {k += pow(pheromone[j][i], alpha) * pow(heuristic[j][i], beta);q = i;}}return q;}城市选择代码:private int choosechengshi() {//用来random的随机数double m = 0;//获得当前所在的城市号放入j,如果和j相邻的城市没有被访问,那么加入mfor (int i = 1, j = tour[n]; i < pheromone.length; i++) {if (!visited[i]) {m += pow(pheromone[j][i], alpha) * pow(heuristic[j][i], beta);}}//保存随机数double p = m * random();//寻找随机城市double k = 0;//保存城市int q = 0;for (int i = 1, j = tour[n]; k < p; i++) {if (!visited[i]) {k += pow(pheromone[j][i], alpha) * pow(heuristic[j][i], beta);q = i;}}return q;}4、算法运行收敛图(即运行到第几步,求得的最优值是多少):run:本次为倒数第100次迭代,当前最优路径长度为41634.60本次为倒数第99次迭代,当前最优路径长度为41514.21本次为倒数第98次迭代,当前最优路径长度为38511.61本次为倒数第97次迭代,当前最优路径长度为38511.61本次为倒数第96次迭代,当前最优路径长度为38511.61本次为倒数第95次迭代,当前最优路径长度为38511.61本次为倒数第94次迭代,当前最优路径长度为37293.07、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、本次为倒数第6次迭代,当前最优路径长度为37293.07本次为倒数第5次迭代,当前最优路径长度为37293.07本次为倒数第4次迭代,当前最优路径长度为37293.07本次为倒数第3次迭代,当前最优路径长度为37293.07本次为倒数第2次迭代,当前最优路径长度为37293.07本次为倒数第1次迭代,当前最优路径长度为37293.07得到的最优的路径长度为: 37293.075、最终求得的最优解的TSP图像:最优路径如下:→1→9→38→31→44→18→7→28→37→19→6→30→43→27→17→36→46→33→15→12→11→23→14→25→13→20→47→21→39→32→48→5→29→2→26→4→35→45→10→42→24→34→41→16→22→3→40→8→1成功生成(总时间:3 秒)实验结果分析:本次通过JA V A语言实现蚁群优化算法,我们发现虽然我们找到了问题的最优解,但是最优解的收敛性并不乐观,并不能求得问题的精确解,并且随着参数的调节运行结果有随机性。
基于蚁群优化算法的TSP问题求解计算智能实验报告
智能计算实验报告学院:班级:学号:姓名:成绩:日期:实验名称:基于蚁群优化算法的TSP问题求解题目要求:利用蚁群优化算法对给定的TSP问题进行求解,求出一条最短路径。
蚁群优化算法简介:蚁群算法是一中求解复杂优化问题的启发式算法,该方法通过模拟蚁群对“信息素”的控制和利用进行搜索食物的过程,达到求解最优结果的目的。
它具有智能搜索、全局优化、稳健性强、易于其它方法结合等优点,适应于解决组合优化问题,包括运输路径优化问题。
TSP数据文件格式分析:本次课程设计采用的TSP文件是att48.tsp ,文件是由48组城市坐标构成的,文件共分成三列,第一列为城市编号,第二列为城市横坐标,第三列为城市纵坐标。
数据结构如下所示:实验操作过程:1、TSP文件的读取:class chengshi {int no;double x;double y;chengshi(int no, double x, double y) {this.no = no;this.x = x;this.y = y;}private double getDistance(chengshi chengshi) {return sqrt(pow((x - chengshi.x), 2) + pow((y - chengshi.y), 2));}}try {//定义HashMap保存读取的坐标信息HashMap<Integer, chengshi> map = new HashMap<Integer,chengshi>();//读取文件BufferedReader reader = new BufferedReader(new (new )));for (String str = reader.readLine(); str != null; str = reader.readLine()) { //将读到的信息保存入HashMapif(str.matches("([0-9]+)(\\s*)([0-9]+)(.?)([0-9]*)(\\s*)([0-9]+)(.?)([0-9]*)")) {String[] data = str.split("(\\s+)");chengshi chengshi = new chengshi(Integer.parseInt(data[0]),Double.parseDouble(data[1]),Double.parseDouble(data[2]));map.put(chengshi.no, chengshi);}}//分配距离矩阵存储空间distance = new double[map.size() + 1][map.size() + 1];//分配距离倒数矩阵存储空间heuristic = new double[map.size() + 1][map.size() + 1];//分配信息素矩阵存储空间pheromone = new double[map.size() + 1][map.size() + 1];for (int i = 1; i < map.size() + 1; i++) {for (int j = 1; j < map.size() + 1; j++) {//计算城市间的距离,并存入距离矩阵distance[i][j] = map.get(i).getDistance(map.get(j));//计算距离倒数,并存入距离倒数矩阵heuristic[i][j] = 1 / distance[i][j];//初始化信息素矩阵pheromone[i][j] = 1;}}} catch (Exception exception) {System.out.println("初始化数据失败!");}}2、TSP作图处理:private void evaporatePheromone() {for (int i = 1; i < pheromone.length; i++)for (int j = 1; j < pheromone.length; j++) {pheromone[i][j] *= 1-rate;}}3、关键源代码(带简单的注释):蚂蚁类代码:class mayi {//已访问城市列表private boolean[] visited;//访问顺序表private int[] tour;//已访问城市的个数private int n;//总的距离private double total;mayi() {//给访问顺序表分配空间tour = new int[distance.length+1];//已存入城市数量为n,刚开始为0n = 0;//将起始城市1,放入访问结点顺序表第一项tour[++n] = 1;//给已访问城市结点分配空间visited = new boolean[distance.length];//第一个城市为出发城市,设置为已访问visited[tour[n]] = true;}private int choosechengshi() {//用来random的随机数double m = 0;//获得当前所在的城市号放入j,如果和j相邻的城市没有被访问,那么加入mfor (int i = 1, j = tour[n]; i < pheromone.length; i++) {if (!visited[i]) {m += pow(pheromone[j][i], alpha) * pow(heuristic[j][i], beta);}}//保存随机数double p = m * random();//寻找随机城市double k = 0;//保存城市int q = 0;for (int i = 1, j = tour[n]; k < p; i++) {if (!visited[i]) {k += pow(pheromone[j][i], alpha) * pow(heuristic[j][i], beta);q = i;}}return q;}城市选择代码:private int choosechengshi() {//用来random的随机数double m = 0;//获得当前所在的城市号放入j,如果和j相邻的城市没有被访问,那么加入mfor (int i = 1, j = tour[n]; i < pheromone.length; i++) {if (!visited[i]) {m += pow(pheromone[j][i], alpha) * pow(heuristic[j][i], beta);}}//保存随机数double p = m * random();//寻找随机城市double k = 0;//保存城市int q = 0;for (int i = 1, j = tour[n]; k < p; i++) {if (!visited[i]) {k += pow(pheromone[j][i], alpha) * pow(heuristic[j][i], beta);q = i;}}return q;}4、算法运行收敛图(即运行到第几步,求得的最优值是多少):run:本次为倒数第100次迭代,当前最优路径长度为41634.60本次为倒数第99次迭代,当前最优路径长度为41514.21本次为倒数第98次迭代,当前最优路径长度为38511.61本次为倒数第97次迭代,当前最优路径长度为38511.61本次为倒数第96次迭代,当前最优路径长度为38511.61本次为倒数第95次迭代,当前最优路径长度为38511.61本次为倒数第94次迭代,当前最优路径长度为37293.07、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、本次为倒数第6次迭代,当前最优路径长度为37293.07本次为倒数第5次迭代,当前最优路径长度为37293.07本次为倒数第4次迭代,当前最优路径长度为37293.07本次为倒数第3次迭代,当前最优路径长度为37293.07本次为倒数第2次迭代,当前最优路径长度为37293.07本次为倒数第1次迭代,当前最优路径长度为37293.07得到的最优的路径长度为: 37293.075、最终求得的最优解的TSP图像:最优路径如下:→1→9→38→31→44→18→7→28→37→19→6→30→43→27→17→36→46→33→15→12→11→23→14→25→13→20→47→21→39→32→48→5→29→2→26→4→35→45→10→42→24→34→41→16→22→3→40→8→1成功生成(总时间:3 秒)实验结果分析:本次通过JA V A语言实现蚁群优化算法,我们发现虽然我们找到了问题的最优解,但是最优解的收敛性并不乐观,并不能求得问题的精确解,并且随着参数的调节运行结果有随机性。
TSP问题——实验报告
TSP问题目录1实验目的 (1)2问题描述与分析 (1)3算法分析 (1)3.1回溯法 (1)3.2 动态规划 (1)3.3 模拟退火算法 (2)4程序设计 (2)4.1回溯法 (2)4.2动态规划算法 (3)4.3模拟退火算法 (4)5实验结果及分析 (5)6实验总结 (6)7源代码 (6)1实验目的1.使用搜索方法进行TSP问题的求解2.了解相关智能算法3.了解NP难问题的求解策略2问题描述与分析某售货员要到若干城市去推销商品,已知各城市之间的路程(或旅费)。
他要选定一条从驻地出发,经过每个城市一遍,最后回到驻地的路线,使总的路程(或旅费)最小。
分析:问题的本质是搜索问题,而且这个问题是NP完全问题,问题的复杂度指数增长,所以普通的搜索无法在有限的时间里完成搜索,尽管有各种优化的算法:启发式算法、深度优先搜索、动态规划、回溯等。
都无法改变复杂度。
实际上大多时候人们并不关心NP完全问题的最优解,只要得出一个近似的解就可以了,因此,人们发明了很多算法,例如粒子群算法、遗传算法、模拟退火算法,这一类算法被称为“智能算法”,但是,他们都无法求出最优解,仅能得到近似解,但这已经足够了。
在本次试验中,一共设计了三个算法:回溯法,动态规划,模拟退火算法。
3算法分析3.1回溯法回溯法采用深度优先方式系统地搜索问题的所有解,基本思路是:确定解空间的组织结构之后,从根结点出发,即第一个活结点和第一个扩展结点向纵深方向转移至一个新结点,这个结点成为新的活结点,并成为当前扩展结点。
如果在当前扩展结点处不能再向纵深方向转移,则当前扩展结点成为死结点。
此时,回溯到最近的活结点处,并使其成为当前扩展结点,回溯到以这种工作方式递归地在解空间中搜索,直到找到所求解空间中已经无活结点为止。
旅行商问题的解空间是一棵排列树.对于排列树的回溯搜索与生成1,2,……, n的所有排列的递归算法Perm类似,设开始时x=[ 1,2,… n ],则相应的排列树由x[ 1:n ]的所有排列构成.旅行商问题的回溯算法。
遗传算法求解TSP问题报告
遗传算法求解TSP问题实验报告一、实验要求:以旅行商问题(TSP)为例做模拟进化搜索技术实验,并提交实验研究报告。
二、实验思路:bool fnCreateRandomGene(); //产生随机基因bool fnGeneAberrance(); //基因变异bool fnGeneMix(); //基因交叉产生新的个体测试并淘汰适应度低的个体bool fnEvalAll(); //测试所有基因的适应度int fnEvalOne(T &Gene); //测试某一个基因的适应度void Crossover( int nFatherA, int nFatherB);void fnDispProbability(); //显示每个个体的权值Crossover()——两染色体的交叉实现输入参数:1、nFatherA 父染色体A2、nFatherB 父染色体B3、nMode 交叉方式返回值:空注:现有交叉方式1、常规交叉方式,该方式比《现代计算方法》(邢文训等编著)p178给出的“非常规码的常规交配法”稍复杂些。
书中只随机选择一个交配位,两个后代交配位之前的基因分别继承双亲的交配位之前的基因。
本程序中,是随机选择两个不相同的交配位,后代在这两个交配位之间继承双亲在这两个交配位之间的基因如父A 1 2 3 | 4 5 6 7 | 8 9 10父B 4 7 8 | 3 2 5 9 | 1 6 10子A 8 3 2 | 4 5 6 7 | 9 1 10子B 1 4 6 | 3 2 5 9 | 7 8 102、贪心交叉方式(Greedy Crossover),具体算法可参见谢胜利,等.求解TSP问题的一种改进的遗传算法[J].计算机工程与应用,2002(8):58~245.三、实验代码:#include <fstream>#include<iostream>#include <vector>#include <algorithm>#include<math.h>#include <time.h>#include <stdlib.h>#include "def.h"#include "TSP.h"void main(){ifstream input_file;ofstream output_file;time_t time1,time2;int _GENERATION_AMOUNT;int times;int _CITY_AMOUNT=-1;int ii,j,k;std::vector<double> x;std::vector<double> y;char readfile[50];const char* writefile="tsp.txt";double tempx[10000],tempy[10000];cout<<"打开城市坐标文件:";cin>>readfile;input_file.open(readfile);if(!input_file){cout<<"打开错误!";return;}cout<<"读入城市坐标........"<<endl;while(1){if(!input_file.eof()){_CITY_AMOUNT++;input_file>>tempx[_CITY_AMOUNT]>>tempy[_CITY_AMOUNT];if(tempx[_CITY_AMOUNT]<0||tempy[_CITY_AMOUNT]<0){cout<<"文件格式有误!";return;}}elsebreak;}if( _CITY_AMOUNT==-1){cout<<"文件格式有误!";return;}input_file.close();_CITY_AMOUNT=_CITY_AMOUNT+1;x.reserve(_CITY_AMOUNT);y.reserve(_CITY_AMOUNT);lpCityDistance.reserve(_CITY_AMOUNT*_CITY_AMOUNT);for(k=0;k<_CITY_AMOUNT;k++){x[k]=tempx[k];y[k]=tempy[k];}cout<<"已存入的城市信息为:"<<endl;for(ii=0;ii<_CITY_AMOUNT;ii++)cout<<"第"<<ii+1<<"个城市"<<"("<<x[ii]<<","<<y[ii]<<")"<<endl;lpCityDistance.clear();for(k=0;k<_CITY_AMOUNT;k++){lpCityDistance[k*_CITY_AMOUNT+k]=0;for(j=k+1;j<_CITY_AMOUNT;j++){lpCityDistance[k*_CITY_AMOUNT+j]=lpCityDistance[j*_CITY_AMOUNT+k] =sqrt((x[k]-x[j])*(x[k]-x[j])+(y[k]-y[j])*(y[k]-y[j]));}}cout<<"输入进化代数:"<<endl;cin>>times;cout<<"输入种群大小:(大于城市个数小于10000)"<<endl;cin>> _GENERATION_AMOUNT;while(_GENERATION_AMOUNT>=10000||_GENERATION_AMOUNT<_CITY_AMOUNT){cout<<"种群数输入错误!请重新输入(大于城市个数小于10000)"<<endl;cin>> _GENERATION_AMOUNT;}Csga<_CONTAINER, _CONTAINER_P> CUnit(times,_GENERATION_AMOUNT,_CITY_AMOUNT); //初始化time1=time(NULL);//开始遗传算法if(!CUnit.fnCreateRandomGene()) //产生随机基因//产生随机的基因{exit(0);}//循环基因编译,杂交,淘汰过程CUnit.fnEvalAll(); //测试所有基因的适应度for ( int i = 0; i<times; ++i ){//CUnit.fnDispProbability();//显示每个个体的权值CUnit.fnGeneAberrance(); //基因变异//基因变异//CUnit.fnDispProbability();//显示每个个体的权值CUnit.fnGeneMix();//交叉产生新的个体测试并淘汰适应度低的个体//基因杂交CUnit.fnEvalAll(); //测试所有基因的适应度// 每隔_DISP_INTERV AL显示一次结果if ( (i+1)%_DISP_INTERV AL == 0 || i == 0){cout << "第" << i+1 << "代" <<endl;CUnit.fnDispProbability();CUnit.fnDispHistoryMin();}}CUnit.fnDispHistoryMin();time2=time(NULL);cout<<"\n\n计算用时为:"<<difftime(time2,time1)<<"s"<<endl;}四、实验结果:。
TSPProblem -
实验一:TSP问题姓名:*班级:*学号:*邮箱:*一、问题描述TSP问题(旅行商问题)是指旅行家要旅行n个城市,要求各个城市经历且仅经历一次然后回到出发城市,并要求所走的路程最短。
此问题可描述如下:设G=(V,E)是一个具有边成本Cij的有向图,Cij的定义如下,对于所有的i和j,Cij>0。
令|V|=n,并假设n>1。
G 的一条周游路线是包含V中每个结点的有向环,周游路线的成本是此路线上所有边的成本和。
二、算法描述旅行商问题要从图G的所有周游路线中求取最小成本的周游路线,而从初始点出发的周游路线一共有(n-1)!条,即等于除初始结点外的n-1个结点的排列数,因此旅行商问题是一个排列问题。
排列问题比子集合的选择问题通常要难于求解得多,这是因为n个物体有n!种排列。
而n个城市有(n-1)!条周游路线,从中找出一条具有最小成本的周游路线的算法,其计算时间显然为O(n!)。
把所有的节点用坐标值表示,用欧式距离的求解方式求出距离矩阵WEIGHT。
把所有节点表示成树的形式,把当前节点表示为根节点,当前节点可到的所有节点表示成其子节点,因为需要求出最优解,所以采用回溯算法来求解。
把所求的最优解表示成一个n元组bestX(N1,N2,…Nn),在求解过程中通过FL来存储当前路径总距离,通过n元组X(N1.N2…)来存储当前所走的路径,在过程中如果发现当前路径CL<FL,把CL的值赋予FL,且回溯。
在回溯过程中没走一次都要判断当前节点是否走过,通过判断节点的值和X组中存储的节点是否相同可以判断节点是否可走。
因为用回溯法求解时间复杂度是O(n!),当节点比较多的时候,需要的量的时间才能求出结果。
所以对回溯算法进行了一些优化。
把贪心算法求出的解当做上界赋予FL,当在某个节点处判断出当前路径距离>FL上界,减去这个分支,此分支后面的节点全部不做判断。
通过贪心算法求出上界,即从初始节点开始,没一都选取当前节点可走的最小距离。
遗传算法求解TSP问题实验报告(仅供参照)
人工智能实验报告实验六遗传算法实验II一、实验目的:熟悉和掌握遗传算法的原理、流程和编码策略,并利用遗传求解函数优化问题,理解求解TSP问题的流程并测试主要参数对结果的影响。
二、实验原理:旅行商问题,即TSP问题(Traveling Salesman Problem)是数学领域中著名问题之一。
假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路经的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。
路径的选择目标是要求得的路径路程为所有路径之中的最小值。
TSP问题是一个组合优化问题。
该问题可以被证明具有NPC计算复杂性。
因此,任何能使该问题的求解得以简化的方法,都将受到高度的评价和关注。
遗传算法的基本思想正是基于模仿生物界遗传学的遗传过程。
它把问题的参数用基因代表,把问题的解用染色体代表(在计算机里用二进制码表示),从而得到一个由具有不同染色体的个体组成的群体。
这个群体在问题特定的环境里生存竞争,适者有最好的机会生存和产生后代。
后代随机化地继承了父代的最好特征,并也在生存环境的控制支配下继续这一过程。
群体的染色体都将逐渐适应环境,不断进化,最后收敛到一族最适应环境的类似个体,即得到问题最优的解。
要求利用遗传算法求解TSP问题的最短路径。
三、实验内容:1、参考实验系统给出的遗传算法核心代码,用遗传算法求解TSP的优化问题,分析遗传算法求解不同规模TSP问题的算法性能。
2、对于同一个TSP问题,分析种群规模、交叉概率和变异概率对算法结果的影响。
3、增加1种变异策略和1种个体选择概率分配策略,比较求解同一TSP问题时不同变异策略及不同个体选择分配策略对算法结果的影响。
4、上交源代码。
四、实验报告要求:1、画出遗传算法求解TSP问题的流程图。
2、分析遗传算法求解不同规模的TSP问题的算法性能。
规模越大,算法的性能越差,所用时间越长。
3、对于同一个TSP问题,分析种群规模、交叉概率和变异概率对算法结果的影响。
分支限界法实验报告
分支限界法实验报告引言分支限界法是一种解决组合优化问题的常用方法,该方法通过对问题空间进行分割,并使用上、下界进行限制,从而快速得到较优解。
在本次实验中,我们主要使用分支限界法解决旅行商问题(TSP),即给定一组城市和各城市之间的距离,求解经过所有城市且距离之和最小的路径。
实验目的本次实验的目的是通过编写程序,利用分支限界法求解旅行商问题,并分析算法的效率和求解结果的优劣。
实验过程问题模型我们使用邻接矩阵来表示城市之间的距离,并通过回溯法和分支限界法来求解最优解。
其中,回溯法用于生成所有可能的路径,而分支限界法则用于剪枝和获取最优解。
在分支限界法中,我们将问题抽象为一个树形结构,树的每个节点代表选择了某一条路径。
同时,我们定义一个上界来限制搜索的范围,并实时更新下界以筛选一些无效的路径。
通过不断剪枝和对路径进行排序,我们最终可以得到最优解。
算法实现我们使用Python语言实现了分支限界法求解旅行商问题的算法。
具体实施步骤如下:步骤1:生成邻接矩阵根据给定的城市和距离,我们首先生成一个邻接矩阵,用于表示各个城市之间的距离。
步骤2:初始化数据结构我们使用一个优先队列来保存当前搜索的路径,并将起始城市加入队列。
同时,我们定义一个全局变量来保存最优路径和当前最优路径的长度。
步骤3:搜索路径通过递归的方式,不断进行路径的搜索。
在搜索过程中,我们使用上、下界和分支限界来进行剪枝操作,并实时更新最优路径信息。
步骤4:输出结果最终,我们得到的最优路径就是旅行商问题的解。
我们将其输出,并统计算法的运行时间。
实验结果实验数据我们使用了一个包含20个城市的实例进行测试,城市之间距离的数据如下:城市距离-1 -2 101 - 3 15... ...19-20 12结果分析经过多次实验,我们得到了最优路径如下:1 -> 3 -> 10 -> 5 -> 17 ->2 -> 12 -> 11 -> 4 -> 9 -> 16 -> 6 -> 19 -> 18-> 13 -> 20 -> 15 -> 8 -> 7 -> 14 -> 1该路径的总距离为123,是经过所有城市且距离之和最小的路径。
回溯法求解TSP问题
回溯法求解T S P问题-CAL-FENGHAI-(2020YEAR-YICAI)_JINGBIAN人工智能实验报告实验名称:TSP问题姓名:xxx学号:xxxxx大学计算机学院2014年1月14日一.实验目的掌握递归回溯法的思想,能够求解TSP 问题,增强自己的编程能力.二.实验内容下图是5个城市的交通图,城市之间的连线权重表示城市之间路程的费用。
要求从A 城出发,经过其它城市一次且仅一次,最后回到A 城,找出一条费用最低的回路。
请用伪代码形式描述所设计的算法。
BDE三、回溯法思想: 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标。
但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
若已有满足约束条件的部分解,不妨设为(x1,x2,x3,……xi ),I<n,则添加x(i+1)属于s(i+2),检查 (x1,x2,……,xi,x(i+1))是否满足条件,满足了就继续添加x(i+2)、s(i+2),若所有的x(i+1)属于s(i+1)都不能得到 部分解,就去掉xi ,回溯到(xi,x2,……x(i- 1)),添加那些未考察过的x1属于s1,看其是否满足约束条件,为此反复进行,直至得到解或证明无解。
四、算法流程:五、关键技术:1、使用了递归回溯法,通过递归调用,节省了代码量,使代码更简洁易懂。
关键代码:void Backtracking(int cityId, int depth, int len) { ize(); i++) { econd] == false) {econd] = true;pre[tab[cityId][i].second] = cityId;Backtracking(tab[cityId][i].second, depth + 1, len +tab[cityId][i].first); econd] = -1;econd] = false; ush_back(PII(w, v));ush_back(PII(w, u)); ush_back(PII(w, v));tab[nodeId][i].first tab[nodeId][i].second六、实验心得1、重温了算法课程里面学过的回溯法,强化了这种编程思想。
TSP问题报告 算法分析与设计
TSP问题一、问题描述所谓 TSP 问题是指旅行商要去 n 个城市推销商品,其中每个城市到达且仅到达一次,并且要求所走的路程最短(该问题又称货郎担问题、邮递员问题、售货员问题等)。
TSP 问题最容易想到、也肯定能得到最优解的算法是穷举法,即考察所有可能的行走线路,从中选出最佳的一条。
二、解题思路1.基本思路对于图G=(V,E),从起点出发,其余点作为路径集合,然后列出路径集合中各个点作为子路径起点,其余点作为路径集合的情况,从中选取路径长度最短的情况,再对路径集合迭代计算,直到路径集合为空的时候,这时最短路径的情况即是该点到原点的距离,路径集合是空集{},此时已触碰临界条件,可以不断回溯之前的迭代,进而解决此问题。
2.最优值函数和边界条件第二行是最优值函数。
从i到集合V'的最优路径是以V’中某一点作为子路径起点,其余点作为路径集合的路径的长度加上从k到i 的距离的最优值。
第一行是边界条件。
当子路径的路径集合是空集时,最优子问题的解,本题来说也就是子路径的最短路径就是从子路径的起点到原来起点的距离。
3.标记函数标记函数同时也是算法的核心函数,完全按照递推公式的思想,使用迭代的方式。
distance是第一个核心函数,主要负责路径的输出;distance1是第二个核心函数,主要负责寻求子集合的最短路径并计算长度。
第一核心函数中调用了第二核心函数,第一核心函数只负路径的输出,在将问题细化深入的过程中,将真正的路径寻找和计算交给第二核心函数。
4.标记函数的解读:(1)distancedouble distance(int a,int b[],int c,double d[][NUM],int start) a:子问题起点b[]:字问题路径集合d[][]:距离矩阵(最开始创建的,所有调用函数过程中,都使用的这个,没有更改,只有读取)start:原问题起点(达到临界条件时,找到路径长度)//边界条件if(c==0){cout<<start;return d[a][start];}//非临界条件时候,构建所有路径集合的,起点和对应的路径集合,在迭代的时候会使用到else{for(i=0;i<c;i++){point[i]=b[i];k=0;for(j=0;j<c;j++){if(i!=j){e[i][k]=b[j]; /*节点方阵,冗余的*/k++;}}}mindistance=distance1(point[k],e[k],c-1,d,start)+d[a][point[k] ];//假定下一层的最短路径就是p[0]以及其对应的路径矩阵e[k]for(i=0;i<c-1;i++) //比较出下一层真正的最短路径if(mindistance>(distance1(point[i+1],e[i+1],c-1,d,start)+d[ a][point[i+1]])){k=i+1;mindistance=distance1(point[k],e[k],c-1,d,start)+d[a][poin t[k]];}cout<<point[k]<<"->";return distance(point[k],e[k],c-1,d,start)+d[a][point[k]]; }(2)distance1double distance1(int a,int b[],int c,double d[][NUM],int start) //边界条件if(c==0){return d[a][start];}//非边界条件else{for(i=0;i<c;i++){point[i]=b[i];k=0;for(j=0;j<c;j++){if(i!=j){e[i][k]=b[j];k++;}}}//拆分该点到达起点所需经过的集合该点的下一点到达起点所需经过的集合mindistance=distance1(point[0],e[0],c-1,d,start)+d[a][point[ 0]];for(i=0;i<c-1;i++)if(mindistance>(distance1(point[i+1],e[i+1],c-1,d,start)+d[ a][point[i+1]]))mindistance=distance1(point[i+1],e[i+1],c-1,d,start)+d[a][ point[i+1]];return mindistance; //求最小值}}5.时间复杂度分析整体的时间复杂度是O (2^n )。
动态规划法-回溯法-分支限界法求解TSP问题实验报告
动态规划法-回溯法-分支限界法求解TSP问题实验报告TSP问题算法实验报告指导教师:季晓慧姓名:辛瑞乾学号: 1004131114 提交日期: 2015年11月目录总述 (4)动态规划法 (4)算法问题分析 (4)算法设计 (5)实现代码 (6)输入输出截图 (10)OJ提交截图 (10)算法优化分析 (10)回溯法 (11)算法问题分析 (11)算法设计 (11)实现代码 (12)输入输出截图 (17)OJ提交截图 (17)算法优化分析 (17)分支限界法 (18)算法问题分析 (18)算法设计 (19)实现代码 (20)输入输出截图 (29)OJ提交截图 (29)算法优化分析 (29)总结 (30)总述TSP问题又称为旅行商问题,是指一个旅行商要历经所有城市一次最后又回到原来的城市,求最短路程或最小花费,解决TSP可以用好多算法,比如蛮力法,动态规划法…具体的时间复杂的也各有差异,本次实验报告包含动态规划法,回溯法以及分支限界法。
动态规划法算法问题分析假设n个顶点分别用0~n-1的数字编号,顶点之间的代价存放在数组mp[n][n]中,下面考虑从顶点0出发求解TSP问题的填表形式。
首先,按个数为1、2、…、n-1的顺序生成1~n-1个元素的子集存放在数组x[2^n-1]中,例如当n=4时,x[1]={1},x[2]={2},x[3]={3},x[4]={1,2},x[5 ]={1,3},x[6]={2,3},x[7]={1,2,3}。
设数组dp[n][2^n-1]存放迭代结果,其中dp[i][j]表示从顶点i经过子集x[j]中的顶点一次且一次,最后回到出发点0的最短路径长度,动态规划法求解TSP问题的算法如下。
算法设计输入:图的代价矩阵mp[n][n]输出:从顶点0出发经过所有顶点一次且仅一次再回到顶点0的最短路径长度1.初始化第0列(动态规划的边界问题)for(i=1;i<n;i++)dp[i][0]=mp[i][0]2.依次处理每个子集数组x[2^n-1]for(i=1;i<n;i++)if(子集x[j]中不包含i)对x[j]中的每个元素k,计算d[i][j]=min{mp[i][k]+dp[k][j-1]};3.输出最短路径长度。
动态规划法,回溯法,分支限界法求解TSP问题实验报告
#define rson m + 1 , r , rt << 1 | 1
using namespace std;
int mp[20][20];
int x[30],vis[30];
int n,k,cur,ans;
void init()
{
for(int i=0;i<n;i++)
{
mp[i][j]=inf;
continue;
}
int tmp;
scanf("%d",&tmp);
mp[i][j]=tmp;
}
}
int mx=(1<<(n-1));
dp[0][0]=0;
for(int i=1; i<n; i++)
{
dp[i][0]=mp[i][0];
}
dp[0][mx-1]=inf;
实现代码
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
算法设计
输入:图的代价矩阵mp[n][n]
输出:从顶点0出发经过所有顶点一次且仅一次再回到顶点0的最短路径长度
TSP问题求解实验报告(word文档良心出品)
TSP问题求解(一)实验目的熟悉和掌握遗传算法的原理,流程和编码策略,并利用遗传求解函数优化问题,理解求解TSP问题的流程并测试主要参数对结果的影响。
(二)实验原理巡回旅行商问题给定一组 n 个城市和俩俩之间的直达距离,寻找一条闭合的旅程,使得每个城市刚好经过一次且总的旅行距离最短。
TSP 问题也称为货郎担问题,是一个古老的问题。
最早可以追溯到 1759 年 Euler提出的骑士旅行的问题。
1948 年,由美国兰德公司推动, TSP成为近代组合优化领域的典型难题。
TSP 是一个具有广泛的应用背景和重要理论价值的组合优化问题。
近年来,有很多解决该问题的较为有效的算法不断被推出,例如 Hopfield 神经网络方法,模拟退火方法以及遗传算法方法等。
TSP搜索空间随着城市数n 的增加而增大 , 所有的旅程路线组合数为 (n-1)!/2。
在如此庞大的搜索空间中寻求最优解,对于常规方法和现有的计算工具而言,存在着诸多计算困难。
借助遗传算法的搜索能力解决TSP问题,是很自然的想法。
基本遗传算法可定义为一个8 元组:(SGA)=( C, E,P0, M,Φ,Г,Ψ ,Τ)C ——个体的编码方法,SGA 使用固定长度二进制符号串编码方法;E——个体的适应度评价函数;P0——初始群体;M ——群体大小,一般取20—100;Ф——选择算子,SGA使用比例算子;Г——交叉算子,SGA使用单点交叉算子;Ψ——变异算子,SGA使用基本位变异算子;Т——算法终止条件,一般终止进化代数为 100—500;问题的表示对于一个实际的待优化问题,首先需要将其表示为适合于遗传算法操作的形式。
用遗传算法解决 TSP,一个旅程很自然的表示为 n 个城市的排列,但基于二进制编码的交叉和变异操作不能适用。
路径表示是表示旅程对应的基因编码的最自然,最简单的表示方法。
它在编码,解码,存储过程中相对容易理解和实现。
例如:旅程( 5-1-7-8-9-4-6-2-3)可以直接表示为( 5 1 7 894623 )(三)实验内容N>=8。
TSP问题遗传算法求解实验报告
一、旅行商问题所谓旅行商问题(Travelling Salesman Problem , TSP),即最短路径问题,就是在给定的起始点S到终止点T的通路集合中,寻求距离最小的通路,这样的通路成为S点到T点的最短路径。
在寻找最短路径问题上,有时不仅要知道两个指定顶点间的最短路径,还需要知道某个顶点到其他任意顶点间的最短路径。
遗传算法方法的本质是处理复杂问题的一种鲁棒性强的启发性随机搜索算法,用遗传算法解决这类问题,没有太多的约束条件和有关解的限制,因而可以很快地求出任意两点间的最短路径以及一批次短路径。
假设平面上有n个点代表n个城市的位置, 寻找一条最短的闭合路径, 使得可以遍历每一个城市恰好一次。
这就是旅行商问题。
旅行商的路线可以看作是对n个城市所设计的一个环形, 或者是对一列n个城市的排列。
由于对n个城市所有可能的遍历数目可达(n- 1)!个, 因此解决这个问题需要0(n!)的计算时间。
假设每个城市和其他任一城市之间都以欧氏距离直接相连。
也就是说, 城市间距可以满足三角不等式, 也就意味着任何两座城市之间的直接距离都小于两城市之间的间接距离。
二、遗传算法1 遗传算法介绍遗传算法是由美国J.Holland教授于1975年在他的专著《自然界和人工系统的适应性》中首先提出的,它是一类借鉴生物界自然选择和自然遗传机制的随机化搜索算法。
通过模拟自然选择和自然遗传过程中发生的繁殖、交叉和基因突变现象,在每次迭代中都保留一组候选解,并按某种指标从解群中选取较优的个体,利用遗传算子(选择、交叉和变异)对这些个体进行组合,产生新一代的候选解群,重复此过程,直到满足某种收敛指标为止。
遗传算法在本质上是一种不依赖具体问题的直接搜索方法,是一种求解问题的高效并行全局搜索方法。
其假设常描述为二进制位串,位串的含义依赖于具体应用。
搜索合适的假设从若干初始假设的群体集合开始。
当前种群成员通过模仿生物进化的方式来产生下一代群体,如随机变异和交叉。
数据结构实验报告-TSP问题
TSP问题一,实验目的熟悉图的数据结构,学会解决实际问题二,实验内容旅行商问题,即TSP问题(Travelling Salesman Problem)又译为旅行推销员问题、货郎担问题,是数学领域中著名问题之一。
假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。
路径的选择目标是要求得的路径路程为所有路径之中的最小值。
三,设计与编码#include<iostream>using namespace std;const int MaxSize = 10;const int Max = 100;int Min(int arr[],int n);class MGraph{public:MGraph(char city[], int n, int e);~MGraph(){}void TSP(int v);private:char vertex[MaxSize];int arc[MaxSize][MaxSize];int vertexNum, arcNum;};int visited[MaxSize] = {0};int main(){char city[] = {'A','B','C','D','E'};MGraph MG(city, 5, 10);MG.TSP(0);return 0;}void MGraph::TSP(int v){cout << vertex[v]; visited[v] = 1;int i = 0,j = 0, s = 0;int log = 0;for(;log < vertexNum;log++){j = Min(arc[i],vertexNum);visited[j] = 1;cout << "->" << vertex[j];i = j;}}int Min(int *p,int n){int start = 0, min = p[0], k = 0;while(visited[start] == 1){start++;min = p[start];}for(;start < n;start++){if((visited[start] == 0) && (min >= p[start])){k = start;min = p[k];}}return k;}//构造函数MGraph::MGraph(char city[], int n, int e){vertexNum = n;arcNum = e;//存储顶点信息for(int i = 0; i < vertexNum; i++)vertex[i] = city[i];//初始化图的邻接矩阵for(int i = 0; i < vertexNum; i++)for(int j = 0; j < vertexNum; j++)arc[i][j] = 100;//存储图的边信息int i,j,weight;for(int k = 0; k < arcNum; k++){cout << "请输入边的两个顶点的序号及其权值:";cin >> i >> j >> weight;arc[i][j] = weight;arc[j][i] = weight;}}四,运行与测试五,总结与心得通过对实际问题的解决,巩固了课本知识,提高了编写代码的能力。
人工智能实验三-TSP问题
【实验名称】人工智能实验三:遗传算法求解TSP问题遗传算法参数(SGA)=(C,E,P0,M,Φ,Г,Ψ,Τ)C ——个体的编码方法;E ——个体的适应度评价函数;P0——初始群体;M ——群体大小,一般取20—100;Ф——选择算子,SGA使用比例算子;Г——交叉算子,SGA使用单点交叉算子;Ψ——变异算子,SGA使用基本位变异算子;Т——算法终止条件,一般终止进化代数为100—500;实验代码:#include <cmath>#include <ctime>#include <vector>#include <map>#include <string>#include <iostream>#include <algorithm>using namespace std;float pcross = 0.80; //交叉率float pmutation = 0.1; //变异率int popsize = 300; //种群大小const int lchrom = 20; //染色体长度int gen; //当前世代int maxgen = 100; //最大世代数int run; //当前运行次数int maxruns =10; //总运行次数float max_var = 9 ; //路径最大连接开销//基因定义(一个城市)struct Gene{string name;map<Gene*,float> linkCost; //该城市到其它城市的路程开销};//染色体定义(到各城市顺序的一种组合)struct Chrom{vector<Gene*> chrom_gene; //染色体(到各城市去的顺序)float varible; //路程总开销float fitness; //个体适应度};//种群定义struct Pop{vector<Chrom> pop_chrom; //种群里的染色体组float sumfitness; //种群中个体适应度累计};Pop oldpop; //当前代种群Pop newpop; //新一代种群vector<Gene> genes(lchrom); //保存全部基因//产生一个随机整数(在low和high之间)inline int randomInt(int low,int high){if(low==high)return low;return low+rand()%(high-low+1);}//计算一条染色体的个体适应度inline void chromCost(Chrom& chr){float sum=0;for(int i=0;i<chr.chrom_gene.size()-1;i++){sum += (chr.chrom_gene[i])->linkCost[chr.chrom_gene[i+1]];}sum += (chr.chrom_gene.front())->linkCost[chr.chrom_gene.back()];chr.varible=sum;chr.fitness=max_var*(lchrom) - chr.varible;}//计算一个种群的个体适应度之和inline void popCost(Pop &pop){float sum=0;for(int i=0;i<pop.pop_chrom.size();i++){sum+=pop.pop_chrom[i].fitness;}pop.sumfitness = sum;}void outChrom(Chrom& chr);//随机初始化一条染色体inline void initChrom(Chrom& chr){vector<int> tmp(lchrom);for(int i=0;i<lchrom;i++)tmp[i]=i;int choose;while(tmp.size()>1){choose=randomInt(0,tmp.size()-1);chr.chrom_gene.push_back(&genes[tmp[choose]]);tmp.erase(tmp.begin()+choose);}chr.chrom_gene.push_back(&genes[tmp[0]]);chromCost(chr);}//随机初始化种群inline void initpop(Pop& pop){pop.pop_chrom.reserve(popsize);Chrom tmp;tmp.chrom_gene.reserve(lchrom);for(int i=0;i<popsize;i++){initChrom(tmp);pop.pop_chrom.push_back(tmp);tmp.chrom_gene.clear();}popCost(pop);}//轮盘赌选择,返回种群中被选择的个体编号inline int selectChrom(const Pop& pop){float sum = 0;float pick = float(randomInt(0,1000))/1000;int i = 0;if(pop.sumfitness!=0){while(1){sum += pop.pop_chrom[i].fitness/pop.sumfitness;i++;if( (sum > pick) || i==pop.pop_chrom.size()-1)return i-1; //??为什么返回29就会出错???}}elsereturn randomInt(0,pop.pop_chrom.size()-2);}//精英策略,返回最优秀的一条染色体inline int chooseBest(const Pop& pop){int choose = 0;float best = 0;for(int i = 0;i< pop.pop_chrom.size();i++){if(pop.pop_chrom[i].fitness > best){best = pop.pop_chrom[i].fitness;choose = i;}}return choose;}//染色体交叉操作,由两个父代产生两个子代(顺序交叉OX)inline void crossover(Chrom& parent1,Chrom& parent2,Chrom& child1,Chrom& child2){child1.chrom_gene.resize(lchrom);child2.chrom_gene.resize(lchrom);vector<Gene*>::iteratorv_iter,p1_beg,p2_beg,c1_beg,c2_beg,p1_end,p2_end,c1_end,c2_end;p1_beg = parent1.chrom_gene.begin();p2_beg = parent2.chrom_gene.begin();c1_beg = child1.chrom_gene.begin();c2_beg = child2.chrom_gene.begin();p1_end = parent1.chrom_gene.end();p2_end = parent2.chrom_gene.end();c1_end = child1.chrom_gene.end();c2_end = child2.chrom_gene.end();vector<Gene*> v1(parent2.chrom_gene), v2(parent1.chrom_gene); //用于交叉的临时表//随机选择两个交叉点int pick1 = randomInt(1,lchrom-3);int pick2 = randomInt(pick1+1,lchrom-2);int dist = lchrom-1-pick2; //第二交叉点到尾部的距离//子代保持两交叉点间的基因不变copy(p1_beg+pick1, p1_beg+pick2+1, c1_beg+pick1);copy(p2_beg+pick1, p2_beg+pick2+1, c2_beg+pick1);//循环移动表中元素rotate(v1.begin(), v1.begin()+pick2+1,v1.end());rotate(v2.begin(), v2.begin()+pick2+1,v2.end());//从表中除去父代已有的元素for(v_iter = p1_beg+pick1; v_iter!=p1_beg+pick2+1; ++v_iter) remove(v1.begin(),v1.end(),*v_iter);for(v_iter = p2_beg+pick1; v_iter!=p2_beg+pick2+1; ++v_iter) remove(v2.begin(),v2.end(),*v_iter);//把表中元素复制到子代中copy(v1.begin(), v1.begin()+dist, c1_beg+pick2+1);copy(v1.begin()+dist, v1.begin()+dist+pick1, c1_beg);copy(v2.begin(), v2.begin()+dist, c2_beg+pick2+1);copy(v2.begin()+dist, v2.begin()+dist+pick1, c2_beg);}//染色体变异操作,随机交换两个基因inline void mutation(Chrom& chr){vector<Gene*>::iterator beg = chr.chrom_gene.begin();int pick1,pick2;pick1 = randomInt(0,lchrom-1);do{pick2 =randomInt(0,lchrom-1);}while(pick1==pick2);iter_swap(beg+pick1, beg+pick2);}//世代进化(由当前种群产生新种群)void generation(Pop& oldpop,Pop& newpop){newpop.pop_chrom.resize(popsize);int mate1,mate2,j;float pick;float tmp;Chrom gene1,gene2,tmp1,tmp2;gene1.chrom_gene.resize(lchrom);gene2.chrom_gene.resize(lchrom);tmp1.chrom_gene.resize(lchrom);tmp2.chrom_gene.resize(lchrom);//将最佳染色体放入下一代mate1 = chooseBest(oldpop);newpop.pop_chrom[0] = oldpop.pop_chrom[mate1];j = 1;//产生两条新染色体do{int count = 0;mate1 = selectChrom(oldpop);mate2 = selectChrom(oldpop);pick = float(randomInt(0,1000))/1000;gene1= oldpop.pop_chrom[mate1];gene2= oldpop.pop_chrom[mate1];if(pick < pcross) //交叉操作{int count = 0;bool flag1 = false;bool flag2 = false;while(1){crossover(oldpop.pop_chrom[mate1],oldpop.pop_chrom[mate2],tmp1,tmp2) ;chromCost(tmp1); //计算适应度chromCost(tmp2);if(tmp1.fitness > gene1.fitness){gene1 = tmp1;flag1 = true;}if(tmp2.fitness > gene2.fitness){gene2 = tmp2;flag2 = true;}if((flag1==true && flag2==true) || count> 50){newpop.pop_chrom[j] = gene1;newpop.pop_chrom[j+1] = gene2;break;}count++;}}else{newpop.pop_chrom[j].chrom_gene = oldpop.pop_chrom[mate1].chrom_gene;newpop.pop_chrom[j+1].chrom_gene = oldpop.pop_chrom[mate2].chrom_gene;chromCost(newpop.pop_chrom[j]);chromCost(newpop.pop_chrom[j+1]);}pick = float(randomInt(0,1000))/1000;if(pick < pmutation) //变异操作{int count = 0;do{tmp = newpop.pop_chrom[j].fitness;mutation(newpop.pop_chrom[j]);chromCost(newpop.pop_chrom[j]); //计算适应度count++;}while(tmp > newpop.pop_chrom[j].fitness && count < 50);}pick = float(randomInt(0,1000))/1000;if(pick < pmutation) //变异操作{int count = 0;do{tmp = newpop.pop_chrom[j+1].fitness;mutation(newpop.pop_chrom[j+1]);chromCost(newpop.pop_chrom[j+1]); //计算适应度count++;}while(tmp > newpop.pop_chrom[j+1].fitness && count < 50);}//chromCost(newpop.pop_chrom[j]); //计算适应度//chromCost(newpop.pop_chrom[j+1]);j += 2;}while(j < popsize-1);popCost(newpop); //计算新种群的适应度之和}//输出一条染色体信息inline void outChrom(Chrom& chr){cout<<endl<<"路径:";for(int i=0;i<lchrom;i++){cout<<chr.chrom_gene[i]->name;}cout<<endl<<"回路总开销:"<<chr.varible<<endl;cout<<"适应度:"<<chr.fitness<<endl;}int main(){cout<<"*************用遗传算法解决TSP问题******************"<<endl;cout<<"*************** E01114336 朱蓉蓉******************"<<endl;stringnames[lchrom]={"A","B","C","D","E","F","G","H","I","J","K","L","M","N", "O","P","Q","R","S","T"};//基因(城市)名称//用矩阵保存各城市间的路程开销float dist[lchrom][lchrom] ={{0, 1, 4, 6, 8, 1, 3, 7, 2, 9, 7, 3, 4, 5, 8, 9, 2, 8, 2, 8},{1, 0, 7, 5, 3, 8, 3, 4, 2, 4, 4, 6, 2, 8, 2, 9, 4, 5, 2, 1},{4, 7, 0, 3, 8, 3, 7, 9, 1, 2, 5, 8, 1, 8, 9, 4, 7, 4, 8, 4},{6, 5, 3, 0, 3, 1, 5, 2, 9, 1, 3, 5, 7, 3, 4, 7, 3, 4, 5, 2},{8, 3, 8, 3, 0, 2, 3, 1, 4, 6, 3, 8, 4, 5, 2, 8, 1, 7, 4, 7},{1, 8, 3, 1, 2, 0, 3, 3, 9, 5, 4, 5, 2, 7, 3, 6, 2, 3, 7, 1},{3, 3, 7, 5, 3, 3, 0, 7, 5, 9, 3, 4, 5, 9, 3, 7, 3, 2, 8, 1},{7, 4, 9, 2, 1, 3, 7, 0, 1, 3, 4, 5, 2, 7, 6, 3, 3, 8, 3, 5},{2, 2, 1, 9, 4, 9, 5, 1, 0, 1, 3, 4, 7, 3, 7, 5, 9, 2, 1, 7},{9, 4, 2, 1, 6, 5, 9, 3, 1, 0, 3, 7, 3, 7, 4, 9, 3, 5, 2, 5},{7, 4, 5, 3, 3, 4, 3, 4, 3, 3, 0, 5, 7, 8, 4, 3, 1, 5, 9, 3},{3, 6, 8, 5, 8, 5, 4, 5, 4, 7, 5, 0, 8, 3, 1, 5, 8, 5, 8, 3},{4, 2, 1, 7, 4, 2, 5, 2, 7, 3, 7, 8, 0, 5, 7, 4, 8, 3, 5, 3},{5, 8, 8, 3, 5, 7, 9, 7, 3, 7, 8, 3, 5, 0, 8, 3, 1, 8, 4, 5},{8, 2, 9, 4, 2, 3, 3, 6, 7, 4, 4, 1, 7, 8, 0, 4, 2, 1, 8, 4},{9, 9, 4, 7, 8, 6, 7, 3, 5, 9, 3, 5, 4, 3, 4, 0, 4, 1, 8, 4},{2, 4, 7, 3, 1, 2, 3, 3, 9, 3, 1, 8, 8, 1, 2, 4, 0, 4, 3, 7},{8, 5, 4, 4, 7, 3, 2, 8, 2, 5, 5, 5, 3, 8, 1, 1, 4, 0, 2, 6},{2, 2, 8, 5, 4, 7, 8,3, 1, 2, 9, 8, 5, 4, 8, 8, 3, 2, 0, 4},{8, 1, 4, 2, 7, 1, 1, 5, 7, 5, 3, 3, 3, 5, 4, 4, 7, 6, 4, 0}};//初始化基因(所有基因都保存在genes中)int i,j;for(i=0;i<lchrom;i++){genes[i].name =names[i];for(j=0;j<lchrom;j++){genes[i].linkCost[&genes[j]] = dist[i][j];}}//输出配置信息cout<<"\n染色体长度:"<<lchrom<<"\n种群大小:"<<popsize<<"\n交叉率:"<<pcross<<"\n变异率:"<<pmutation;cout<<"\n最大世代数:"<<maxgen<<"\n总运行次数:"<<maxruns<<"\n路径最大连接开销:"<<max_var<<endl;//输出路径信息cout<<endl<<" ";for(i=0;i<lchrom;i++)cout<<genes[i].name<<" ";cout<<endl;for(i=0;i<lchrom;i++){cout<<genes[i].name<<":";for(j=0;j<lchrom;j++){cout<<genes[i].linkCost[&genes[j]]<<" ";}cout<<endl;}cout<<endl;int best;Chrom bestChrom; //全部种群中最佳染色体bestChrom.fitness = 0;float sumVarible = 0;float sumFitness = 0;//运行maxrns次for(run = 1;run<=maxruns;run++){initpop(oldpop); //产生初始种群//通过不断进化,直到达到最大世代数for(gen = 1;gen<=maxgen;gen++){generation(oldpop,newpop); //从当前种群产生新种群oldpop.pop_chrom.swap(newpop.pop_chrom);oldpop.sumfitness = newpop.sumfitness;newpop.pop_chrom.clear();}best = chooseBest(oldpop); //本次运行得出的最佳染色体if(oldpop.pop_chrom[best].fitness > bestChrom.fitness)bestChrom = oldpop.pop_chrom[best];sumVarible += oldpop.pop_chrom[best].varible;sumFitness += oldpop.pop_chrom[best].fitness;cout<<run<<"次"<<"Best:";outChrom(oldpop.pop_chrom[best]); //输出本次运行得出的最佳染色体cout<<endl;oldpop.pop_chrom.clear();}cout<<endl<<"一条最佳染色体:";outChrom(bestChrom); //输出全部种群中最佳染色体cout<<endl<<endl<<"最佳染色体平均开销:"<<sumVarible/maxruns;cout<<endl<<"最佳染色体平均适应度:"<<sumFitness/maxruns<<endl;system("PAUSE");return 0;}实验结果截图:。
动态规划法回溯法分支限界法求解TSP问题实验报告
TSP问题算法实验报告指导教师:季晓慧姓名:辛瑞乾学号:提交日期:2015年11月目录总述 ......................................................................动向规划法................................................................算法问题剖析............................................................算法设计................................................................实现代码................................................................输入输出截图............................................................OJ提交截图 ..............................................................算法优化剖析............................................................回溯法 ....................................................................算法问题剖析............................................................算法设计................................................................实现代码................................................................输入输出截图............................................................OJ提交截图 ..............................................................算法优化剖析............................................................分支限界法................................................................算法问题剖析............................................................算法设计................................................................实现代码................................................................输入输出截图............................................................OJ提交截图 ..............................................................算法优化剖析............................................................总结 ......................................................................总述TSP问题又称为旅游商问题,是指一个旅游商要历经全部城市一次最后又回到本来的城市,求最短行程或最小花销,解决TSP能够用好多算法,比方蛮力法,动向规划法⋯详细的时间复杂的也各有差别,本次实验报告包括动态规划法,回溯法以及分支限界法。
实验三10个城的TSP问题
实验三10个城市的TSP问题一、问题描述旅行商问题旅行商按一定的顺序访问N个城市的每个城市,使得每个城市都能被访问且仅能被访问一次,最后回到起点,而使花费的代价最小。
二、设计思想1、算法的选择这是一个NP完全问题,穷举法显然是不可取的。
由于初始态和最终态无法界定,因此没有采用了A*算法。
通过查阅资料,发现模拟退火算法能较好地解决这一问题。
2、算法思想模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。
用固体退火模拟组合优化问题,将内能E模拟为目标函数值f,温度T演化成控制参数t,即得到解组合优化问题的模拟退火算法:由初始解i和控制参数初值t开始,对当前解重复“产生新解→计算目标函数差→接受或舍弃”的迭代,并逐步衰减t值,算法终止时的当前解即为所得近似最优解,这是基于蒙特卡罗迭代求解法的一种启发式随机搜索过程。
3、算法描述模拟退火算法与初始值无关,算法求得的解与初始解状态S(是算法迭代的起点)无关;模拟退火算法具有渐近收敛性,已在理论上被证明是一种以概率p 收敛于全局最优解的全局优化算法。
接受概率p=exp(-Δf/Ti)。
求解TSP的模拟退火算法模型可描述如下:解空间:解空间S是遍访每个城市恰好一次的所有路经,解可以表示为{w1,w2 ,……, wn},w1, ……, wn是1,2,……,n的一个排列,表明w1城市出发,依次经过w2, ……, wn城市,再返回w1城市。
初始解可选为(1,……, n) ;目标函数:目标函数为访问所有城市的路径总长度;我们要求的最优路径为目标函数为最小值时对应的路径。
新路径的产生:随机产生1和n之间的两相异数k和m,不妨假设k<m,则将原路径(w1,w2,…,wk,wk+1,…,wm,wm+1,…,wn)变为新路径:(w1,w2,…,wm,wk+1,…,wk,wm+1,…,wn)上述变换方法就是将k和m对应的两个城市在路径序列中交换位置,称为2-opt映射。
人工智能TSP旅行商问题实验报告
人工智能实验三实验报告班级:姓名:学号:一实验题目TSP问题的遗传算法实现旅行商问题(Traveling Salesman Problem, TSP),又译为旅行推销员问题、货担郎问题,简称为TSP问题,是最基本的路线问题。
假设有n个可直达的城市,一销售商从其中的某一城市出发,不重复地走完其余n-1个城市并回到原出发点,在所有可能的路径中求出路径长度最短的一条。
应用遗传算法求解30/10个节点的TSP(旅行商问题)问题,求问题的最优解。
二实验目的1 熟悉和掌握遗传算法的基本概念和基本思想;2 理解和掌握遗传算法的各个操作算子,能够用选定的编程语言设计简单的遗传优化系统;3 通过实验培养学生利用遗传算法进行问题求解的基本技能。
三实验要求1 掌握遗传算法的基本原理、各个遗传操作和算法步骤;2 要求求出问题最优解,若得不出最优解,请分析原因;3 对实验中的几个算法控制参数进行仔细定义,并能通过实验选择参数的最佳值;4 要求界面显示每次迭代求出的局部最优解和最终求出的全局最优解。
四数据结构请说明染色体个体和群体的定义方法。
struct RanSeTi //染色体的个体的定义方法{int city[cities]; //基因的排列(即城市的顺序,路径的组织)int adapt; //记录适应度double p; //记录其在种群中的幸存概率} RanSeTi [num], RanSeTi temp[num]; //用数组来存储染色体群体方法五实验算法1 说明算法中对染色体的编码方法,适应度函数定义方法1) 染色体的编码方法:即为染色体个体定义过程中生成的基因排列(路径中城市的顺序) struct RanSeTi //染色体的个体的定义方法 {int city[cities]; //基因的排列(即城市的顺序,路径的组织)int adapt; //记录适应度 double p; //记录其在种群中的幸存概率} RanSeTi [num], RanSeTi temp[num]; //用数组来存储染色体群体方法2) 适应度函数定义方法:评价函数即适应度函数,在遗传算法中用来计算一个染色体优劣的函数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
TSP问题求解(一)实验目的熟悉和掌握遗传算法的原理,流程和编码策略,并利用遗传求解函数优化问题,理解求解TSP问题的流程并测试主要参数对结果的影响。
(二)实验原理巡回旅行商问题给定一组n个城市和俩俩之间的直达距离,寻找一条闭合的旅程,使得每个城市刚好经过一次且总的旅行距离最短。
TSP问题也称为货郎担问题,是一个古老的问题。
最早可以追溯到1759年Euler提出的骑士旅行的问题。
1948年,由美国兰德公司推动,TSP成为近代组合优化领域的典型难题。
TSP是一个具有广泛的应用背景和重要理论价值的组合优化问题。
近年来,有很多解决该问题的较为有效的算法不断被推出,例如Hopfield神经网络方法,模拟退火方法以及遗传算法方法等。
TSP搜索空间随着城市数n的增加而增大,所有的旅程路线组合数为(n-1)!/2。
在如此庞大的搜索空间中寻求最优解,对于常规方法和现有的计算工具而言,存在着诸多计算困难。
借助遗传算法的搜索能力解决TSP问题,是很自然的想法。
基本遗传算法可定义为一个8元组:(SGA)=(C,E,P0,M,Φ,Г,Ψ,Τ)C ——个体的编码方法,SGA使用固定长度二进制符号串编码方法;E ——个体的适应度评价函数;P0——初始群体;M ——群体大小,一般取20—100;Ф——选择算子,SGA使用比例算子;Г——交叉算子,SGA使用单点交叉算子;Ψ——变异算子,SGA使用基本位变异算子;Т——算法终止条件,一般终止进化代数为100—500;问题的表示对于一个实际的待优化问题,首先需要将其表示为适合于遗传算法操作的形式。
用遗传算法解决TSP,一个旅程很自然的表示为n个城市的排列,但基于二进制编码的交叉和变异操作不能适用。
路径表示是表示旅程对应的基因编码的最自然,最简单的表示方法。
它在编码,解码,存储过程中相对容易理解和实现。
例如:旅程(5-1-7-8-9-4-6-2-3)可以直接表示为(5 1 7 8 9 4 6 2 3)(三)实验内容N>=8。
随即生成N个城市间的连接矩阵。
指定起始城市。
给出每一代的最优路线和总路线长度。
以代数T作为结束条件,T>=50。
(四)实验代码#include"stdafx.h"#include<stdio.h>#include<string.h>#include<stdlib.h>#include<math.h>#include<time.h>#define cities 10 //城市的个数#define MAXX 100//迭代次数#define pc 0.8 //交配概率#define pm 0.05 //变异概率#define num 10//种群的大小int bestsolution;//最优染色体int distance[cities][cities];//城市之间的距离struct group//染色体的结构{int city[cities];//城市的顺序int adapt;//适应度double p;//在种群中的幸存概率}group[num], grouptemp[num];//随机产生cities个城市之间的相互距离void init(){int i, j;memset(distance, 0, sizeof(distance));srand((unsigned)time(NULL));for (i = 0; i<cities; i++){for (j = i + 1; j<cities; j++){distance[i][j] = rand() % 100;distance[j][i] = distance[i][j];}}//打印距离矩阵printf("城市的距离矩阵如下\n");for (i = 0; i<cities; i++){for (j = 0; j<cities; j++)printf("%4d", distance[i][j]);printf("\n");}}//随机产生初试群void groupproduce(){int i, j, t, k, flag;for (i = 0; i<num; i++) //初始化for (j = 0; j<cities; j++)group[i].city[j] = -1;srand((unsigned)time(NULL));for (i = 0; i<num; i++){//产生10个不相同的数字for (j = 0; j<cities;){t = rand() % cities;flag = 1;for (k = 0; k<j; k++){if (group[i].city[k] == t){flag = 0;break;}}if (flag){group[i].city[j] = t;j++;}}}//打印种群基因printf("初始的种群\n");for (i = 0; i<num; i++){for (j = 0; j<cities; j++)printf("%4d", group[i].city[j]);printf("\n");}}//评价函数,找出最优染色体void pingjia(){int i, j;int n1, n2;int sumdistance, biggestsum = 0;double biggestp = 0;for (i = 0; i<num; i++){sumdistance = 0;for (j = 1; j<cities; j++){n1 = group[i].city[j - 1];n2 = group[i].city[j];sumdistance += distance[n1][n2];}group[i].adapt = sumdistance; //每条染色体的路径总和biggestsum += sumdistance; //种群的总路径}//计算染色体的幸存能力,路劲越短生存概率越大for (i = 0; i<num; i++){group[i].p = 1 - (double)group[i].adapt / (double)biggestsum;biggestp += group[i].p;}for (i = 0; i<num; i++)group[i].p = group[i].p / biggestp; //在种群中的幸存概率,总和为1 //求最佳路劲bestsolution = 0;for (i = 0; i<num; i++)if (group[i].p>group[bestsolution].p)bestsolution = i;//打印适应度for (i = 0; i<num; i++)printf("染色体%d的路径之和与生存概率分别为%4d %.4f\n", i, group[i].adapt, group[i].p);printf("当前种群的最优染色体是%d号染色体\n", bestsolution);}//选择void xuanze(){int i, j, temp;double gradient[num];//梯度概率double xuanze[num];//选择染色体的随机概率int xuan[num];//选择了的染色体//初始化梯度概率for (i = 0; i<num; i++){gradient[i] = 0.0;xuanze[i] = 0.0;}gradient[0] = group[0].p;for (i = 1; i<num; i++)gradient[i] = gradient[i - 1] + group[i].p;srand((unsigned)time(NULL));//随机产生染色体的存活概率for (i = 0; i<num; i++){xuanze[i] = (rand() % 100);xuanze[i] /= 100;}//选择能生存的染色体for (i = 0; i<num; i++){for (j = 0; j<num; j++){if (xuanze[i]<gradient[j]){xuan[i] = j; //第i个位置存放第j个染色体break;}}}//拷贝种群for (i = 0; i<num; i++){grouptemp[i].adapt = group[i].adapt;grouptemp[i].p = group[i].p;for (j = 0; j<cities; j++)grouptemp[i].city[j] = group[i].city[j];}//数据更新for (i = 0; i<num; i++){temp = xuan[i];group[i].adapt = grouptemp[temp].adapt;group[i].p = grouptemp[temp].p;for (j = 0; j<cities; j++)group[i].city[j] = grouptemp[temp].city[j];}//用于测试printf("<------------------------------->\n");for(i=0;i<num;i++){for(j=0;j<cities;j++)printf("%4d",group[i].city[j]);printf("\n");printf("染色体%d的路径之和与生存概率分别为%4d %.4f\n",i,group[i].adapt,group[i].p);}}//交配,对每个染色体产生交配概率,满足交配率的染色体进行交配void jiaopei(){int i, j, k, kk;int t;//参与交配的染色体的个数int point1, point2, temp;//交配断点int pointnum;int temp1, temp2;int map1[cities], map2[cities];double jiaopeip[num];//染色体的交配概率int jiaopeiflag[num];//染色体的可交配情况for (i = 0; i<num; i++)//初始化jiaopeiflag[i] = 0;//随机产生交配概率srand((unsigned)time(NULL));for (i = 0; i<num; i++){jiaopeip[i] = (rand() % 100);jiaopeip[i] /= 100;}//确定可以交配的染色体t = 0;for (i = 0; i<num; i++){if (jiaopeip[i]<pc){jiaopeiflag[i] = 1;t++;}}t = t / 2 * 2;//t必须为偶数//产生t/2个0-9交配断点srand((unsigned)time(NULL));temp1 = 0;//temp1号染色体和temp2染色体交配for (i = 0; i<t / 2; i++){point1 = rand() % cities;point2 = rand() % cities;for (j = temp1; j<num; j++)if (jiaopeiflag[j] == 1){temp1 = j;break;}for (j = temp1 + 1; j<num; j++)if (jiaopeiflag[j] == 1){temp2 = j;break;}//进行基因交配if (point1>point2) //保证point1<=point2{temp = point1;point1 = point2;point2 = temp;}memset(map1, -1, sizeof(map1));memset(map2, -1, sizeof(map2));//断点之间的基因产生映射for (k = point1; k <= point2; k++){map1[group[temp1].city[k]] = group[temp2].city[k];map2[group[temp2].city[k]] = group[temp1].city[k];}//断点两边的基因互换for (k = 0; k<point1; k++){temp = group[temp1].city[k];group[temp1].city[k] = group[temp2].city[k];group[temp2].city[k] = temp;}for (k = point2 + 1; k<cities; k++){temp = group[temp1].city[k];group[temp1].city[k] = group[temp2].city[k];group[temp2].city[k] = temp;}//处理产生的冲突基因for (k = 0; k<point1; k++){for (kk = point1; kk <= point2; kk++)if (group[temp1].city[k] == group[temp1].city[kk]){group[temp1].city[k] = map1[group[temp1].city[k]];break;}}for (k = point2 + 1; k<cities; k++){for (kk = point1; kk <= point2; kk++)if (group[temp1].city[k] == group[temp1].city[kk]){group[temp1].city[k] = map1[group[temp1].city[k]];break;}}for (k = 0; k<point1; k++){for (kk = point1; kk <= point2; kk++)if (group[temp2].city[k] == group[temp2].city[kk]){group[temp2].city[k] = map2[group[temp2].city[k]];break;}}for (k = point2 + 1; k<cities; k++){for (kk = point1; kk <= point2; kk++)if (group[temp2].city[k] == group[temp2].city[kk]){group[temp2].city[k] = map2[group[temp2].city[k]];break;}}temp1 = temp2 + 1;}}//变异void bianyi(){int i, j;int t;int temp1, temp2, point;double bianyip[num]; //染色体的变异概率int bianyiflag[num];//染色体的变异情况for (i = 0; i<num; i++)//初始化bianyiflag[i] = 0;//随机产生变异概率srand((unsigned)time(NULL));for (i = 0; i<num; i++){bianyip[i] = (rand() % 100);bianyip[i] /= 100;}//确定可以变异的染色体t = 0;for (i = 0; i<num; i++){if (bianyip[i]<pm){bianyiflag[i] = 1;t++;}}//变异操作,即交换染色体的两个节点srand((unsigned)time(NULL));for (i = 0; i<num; i++){if (bianyiflag[i] == 1){temp1 = rand() % 10;temp2 = rand() % 10;point = group[i].city[temp1];group[i].city[temp1] = group[i].city[temp2];group[i].city[temp2] = point;}}}int main(){int i, j, t;init();groupproduce();//初始种群评价pingjia();t = 0;while (t++<MAXX){xuanze();//jiaopei();bianyi();pingjia();}//最终种群的评价printf("\n输出最终的种群评价\n");for (i = 0; i<num; i++){for (j = 0; j<cities; j++){printf("%4d", group[i].city[j]);}printf(" adapt:%4d, p:%.4f\n", group[i].adapt, group[i].p);}printf("最优解为%d号染色体\n", bestsolution);system("Pause");}(五)实验结果截图(六)实验心得通过本次实验,使自己对遗传算法有了更进一步的了解。