人工智能实验二基于TSP遗传算法的旅行家问题求解.docx
《人工智能实验二基于TSP遗传算法的旅行家问题求解.docx》由会员分享,可在线阅读,更多相关《人工智能实验二基于TSP遗传算法的旅行家问题求解.docx(18页珍藏版)》请在冰豆网上搜索。
![人工智能实验二基于TSP遗传算法的旅行家问题求解.docx](https://file1.bdocx.com/fileroot1/2023-1/31/e08d32af-9626-45b3-9438-d8d626e9fe29/e08d32af-9626-45b3-9438-d8d626e9fe291.gif)
人工智能实验二基于TSP遗传算法的旅行家问题求解
遗传算法求TSP问题
遗传算法(GeneticAlgorithm)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法,它最初由美国Michigan大学J.Holland教授于1975年首先提出来的,并出版了颇有影响的专著《AdaptationinNaturalandArtificialSystems》,GA这个名称才逐渐为人所知,J.Holland教授所提出的GA通常为简单遗传算法(SGA)。
遗传算法是从代表问题可能潜在的解集的一个种群(population)开始的,而一个种群则由经过基因(gene)编码的一定数目的个体(individual)组成。
每个个体实际上是染色体(chromosome)带有特征的实体。
染色体作为遗传物质的主要载体,即多个基因的集合,其内部表现(即基因型)是某种基因组合,它决定了个体的形状的外部表现,如黑头发的特征是由染色体中控制这一特征的某种基因组合决定的。
因此,在一开始需要实现从表现型到基因型的映射即编码工作。
由于仿照基因编码的工作很复杂,我们往往进行简化,如二进制编码,初代种群产生之后,按照适者生存和优胜劣汰的原理,逐代(generation)演化产生出越来越好的近似解,在每一代,根据问题域中个体的适应度(fitness)大小选择(selection)个体,并借助于自然遗传学的遗传算子(geneticoperators)进行组合交叉(crossover)和变异(mutation),产生出代表新的解集的种群。
这个过程将导致种群像自然进化一样的后生代种群比前代更加适应于环境,末代种群中的最优个体经过解码(decoding),可以作为问题近似最优解。
遗传算法特点
遗传算法是一类可用于复杂系统优化的具有鲁棒性的搜索算法,与传统的优化算法相比,主要有以下特点:
1、遗传算法以决策变量的编码作为运算对象。
传统的优化算法往往直接决策变量的实际值本身,而遗传算法处理决策变量的某种编码形式,使得我们可以借鉴生物学中的染色体和基因的概念,可以模仿自然界生物的遗传和进化机理,也使得我们能够方便的应用遗传操作算子。
2、遗传算法直接以适应度作为搜索信息,无需导数等其它辅助信息。
3、遗传算法使用多个点的搜索信息,具有隐含并行性。
4、遗传算法使用概率搜索技术,而非确定性规则。
/***********************************************************************
*遗传算法解决TSP问题*
*codeby小白atJuly.30*
***********************************************************************/
def.h
-------------------------------
#ifndef_GENERATION_AMOUNT
#define_GENERATION_AMOUNT201//每一代的生存数
#define_CITY_AMOUNT10//城市数,等于基因数
//#define_XCHG_GENE_AMOUNT_WHEN_MIX2//每次杂交所交换的碱基数量
#define_TIMES50//定义进化次数
#define_DISP_INTERVAL5//每隔多少次显示基因中的最高适应度
#define_CONTAINERstd:
:
vector//定义个体基因容器类型
#define_CONTAINER_Pstd:
:
vector//定义适应度容器类型
#define_P(a,x,y)*(a+(x)+(y)*_CITY_AMOUNT)
#define_P_GENE_ABERRANCE10//变异概率1%
#define_P_GENE_MIX(_GENERATION_AMOUNT-1)/2//杂交次数
#define_INFINITE100000
typedefintDISTANCE;//距离矩阵的数据存储类型
#endif
___________________________________________________________________________
TSP.cpp
____________________________________________________________________________
#include
#include
#include
#include
#include
#include"def.h"
#include"TSP.h"
voidmain()
{
conststaticDISTANCEdistance[][_CITY_AMOUNT]
={
0,1,4,6,8,1,3,7,2,9,
1,0,7,5,3,8,3,4,2,4,
4,7,0,3,8,3,7,9,1,2,
6,5,3,0,3,1,5,2,9,1,
8,3,8,3,0,2,3,1,4,6,
1,8,3,1,2,0,3,3,9,5,
3,3,7,5,3,3,0,7,5,9,
7,4,9,2,1,3,7,0,1,3,
2,2,1,9,4,9,5,1,0,1,
9,4,2,1,6,5,9,3,1,0
};//城市间的距离矩阵
//distance[i][j]代表i城市与j城市的距离
/*
conststaticDISTANCEdistance[][_CITY_AMOUNT]
={
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
};
*/
Csga<_CONTAINER,_CONTAINER_P>CUnit((DISTANCE*)distance);//初始化
//开始遗传算法
if(!
CUnit.fnCreateRandomGene())//产生随机的基因
{
exit(0);
}
//循环基因编译,杂交,淘汰过程
CUnit.fnEvalAll();
for(inti=0;i<_TIMES;++i)
{
//CUnit.fnDispProbability();
CUnit.fnGeneAberrance();//基因变异
//CUnit.fnDispProbability();
CUnit.fnGeneMix();//基因杂交
CUnit.fnEvalAll();
//每隔_DISP_INTERVAL显示一次结果
if((i+1)%_DISP_INTERVAL==0||i==0)
{
cout<<"第"<
:
endl;
CUnit.fnDispProbability();
CUnit.fnDispHistoryMin();
}
}
CUnit.fnDispHistoryMin();
}
___________________________________________________________________________
tsp.h
___________________________________________________________________________
#include"def.h"
usingnamespacestd;
template
classCsga
{
public:
Csga();
Csga(DISTANCE*lpDistance);//构造函数
~Csga();//析构函数
boolfnCreateRandomGene();//产生随机基因
boolfnGeneAberrance();//基因变异
boolfnGeneMix();//基因交叉产生新的个体测试并淘汰适应度低的个体
boolfnEvalAll();//测试所有基因的适应度
intfnEvalOne(T&Gene);//测试某一个基因的适应度
voidfnDispProbability();//显示每个个体的权值
voidfnDispHistoryMin();
private:
boolfnGeneAberranceOne(constint&i,constint&j);//变异某个基因
Tm_GenerationGene[_GENERATION_AMOUNT];//定义每个群体的基因
Pm_vProbability;//定义每个群体的适应度
DISTANCE*lpCityDistance;
intHistoryMin;
THistoryMinWay;
Tm_GenerationGeneBk[_GENERATION_AMOUNT];
};
//构造函数
template
Csga:
:
Csga()
{
}
template
Csga:
:
Csga(DISTANCE*lpDistance)
{
lpCityDistance=lpDistance;
m_vProbability.reserve(_CITY_AMOUNT);
HistoryMin=_INFINITE;
//cout<<_P(lpCityDistance,3,2);//调试用
}
//析构函数
template
Csga:
:
~Csga()
{
}
//产生随机基因
template
boolCsga:
:
fnCreateRandomGene()
{
srand(time(0));//初始化随机数
//cout<<"\t基因序列"<:
endl;//调试用
//生成随机基因
for(intj,temp,i=0;i<_GENERATION_AMOUNT;++i)
{
m_GenerationGene[i].reserve(_CITY_AMOUNT);
for(j=0;j<_CITY_AMOUNT;++j)
{
do
{
temp=rand()%_CITY_AMOUNT;
}while(find(m_GenerationGene[i].begin(),m_GenerationGene[i].end(),temp)
!
=m_GenerationGene[i].end());
m_GenerationGene[i].push_back(temp);
}//endfor
/*copy(m_GenerationGene[i].begin(),m_GenerationGene[i].end(),
std:
:
ostream_iterator(cout,""));
cout<:
endl;*///调试用
}
returntrue;
}
//基因变异
template
boolCsga:
:
fnGeneAberrance()
{
inti,j;
inttemp;
srand(time(0));
//抽选一代中的某个基因进行变异
for(i=0;i<_GENERATION_AMOUNT;++i)
{
for(j=0;j<_CITY_AMOUNT;++j)
{
temp=rand()%10000;
if(temp>0&&temp<=_P_GENE_ABERRANCE)
{
//随机抽选到的基因进行变异
if(!
fnGeneAberranceOne(i,j)){exit(0);}
}//endif
}//endforj
}//endfori
returntrue;
}
//变异第i个基因的第j位染色体
template
boolCsga:
:
fnGeneAberranceOne(constint&i,constint&j)
{
inttemp;//基因变异结果
srand(time(0));
T:
:
iteratorpos;
//找到变异位与另外一位交换
pos=std:
:
find(m_GenerationGene[i].begin(),m_GenerationGene[i].end(),temp);
if(pos!
=m_GenerationGene[i].end())
{
*pos=m_GenerationGene[i][j];
m_GenerationGene[i][j]=temp;
returntrue;
}
returnfalse;
}
inlineintfnRndBoundary(intiBegin,intiEnd)
{
returnrand()%(iEnd-iBegin)+iBegin;
}
//基因交叉产生新的个体并淘汰适应度低的个体
template
boolCsga:
:
fnGeneMix()
{
srand(time(0));
std:
:
vectortemp;//选择池
PvProbabilityBk;//临时保存适应度
vProbabilityBk=m_vProbability;
temp.reserve(((_GENERATION_AMOUNT+1)*_GENERATION_AMOUNT)/2);
P:
:
iteratorpos;
for(inti=_GENERATION_AMOUNT;i>0;--i)
{
pos=std:
:
min_element(vProbabilityBk.begin(),vProbabilityBk.end());
temp.insert(temp.end(),i,(int)(pos-vProbabilityBk.begin()));
*pos=_INFINITE;
}
/**************************************************************************
fnDispProbability();
cout<<"\ttemp\n"<:
endl;//调试用
copy(temp.begin(),temp.end(),std:
:
ostream_iterator(cout,""));
cout<:
endl;//调试用
**************************************************************************/
#define_MIN_ELEMENTstd:
:
min_element(m_vProbability.begin(),m_vProbability.end())
m_GenerationGeneBk[_GENERATION_AMOUNT-1]=m_GenerationGene[_MIN_ELEMENT-m_vProbability.begin()];
intiFather;//父亲的代号
intiMother;//母亲的代号
TChild1,Child2;//父亲与母亲杂交出的子女的基因
T:
:
iteratortempIter;
intLowBoundary;
intHighBoundary;
//intiChild1Probability,iChild2Probability;
TfatherBk,motherBk;
T:
:
iteratorV_iter;
P:
:
iteratorP_iter;
intiDistance;
srand(time(0));
#ifndef_ITEMP
#define_ITEMPrand()%(((_GENERATION_AMOUNT+1)*_GENERATION_AMOUNT)/2)
#endif
for(i=0;i<_P_GENE_MIX;++i)//杂交_P_GENE_MIX/10次
{
iFather=temp[_ITEMP];
do
{
iMother=temp[_ITEMP];
}while(iMother==iFather);
Child1.reserve(_CITY_AMOUNT);//初始化子女的碱基数
Child2.reserve(_CITY_AMOUNT);
Child1.clear();
Child2.clear();
LowBoundary=fnRndBoundary(0,_CITY_AMOUNT-2);
HighBoundary=fnRndBoundary(LowBoundary+1,_CITY_AMOUNT-1);
/**********************************************************************
cout<<"iMother:
"<:
endl;
cout<<"iFather:
"<:
endl;
cout<<"LowBoundary:
"<:
endl;
cout<<"HighBoundary:
"<