基本蚁群算法

//=====================================================================
//基本蚁群算法源代码
//使用的城市数据是eil51.tsp
//=====================================================================
// AO.cpp : 定义控制台应用程序的入口点。
#pragma once
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <time.h>
//=====================================================================
//常量定义和参数定义
//=====================================================================
const double ALPHA=1.0; //启发因子,信息素的重要程度
const double BETA=2.0; //期望因子,城市间距离的重要程度
const double ROU=0.5; //信息素残留参数
const int N_ANT_COUNT=34; //蚂蚁数量
const int N_IT_COUNT=1000; //迭代次数
const int N_CITY_COUNT=51; //城市数量
const double DBQ=100.0; //总的信息素
const double DB_MAX=10e9; //一个标志数,10的9次方
double g_Trial[N_CITY_COUNT][N_CITY_COUNT]; //两两城市间信息素,就是环境信息素
double g_Distance[N_CITY_COUNT][N_CITY_COUNT]; //两两城市间距离
//eil51.tsp城市坐标数据
double x_Ary[N_CITY_COUNT]=
{
37,49,52,20,40,21,17,31,52,51,
42,31,5,12,36,52,27,17,13,57,
62,42,16,8,7,27,30,43,58,58,
37,38,46,61,62,63,32,45,59,5,
10,21,5,30,39,32,25,25,48,56,
};

double y_Ary[N_CITY_COUNT]=
{
52,49,64,26,30,47,63,62,33,21,
41,32,25,42,16,41,23,33,13,58,
42,57,57,52,38,68,48,67,48,27,
69,46,10,33,63,69,22,35,15,6,
17,10,64,15,10,39,32,55,28,37,
};
//返回指定范围内的随机整数
int rnd(int nLow,int nUpper)
{
return nLow+(nUpper-nLow)*rand()/(RAND_MAX+1);
}
//返回指定范围内的随机浮点数
double rnd(double dbLow,double dbUpper)
{
double dbTemp=rand()/((double)RAND_MAX+1.0);
return dbLow+dbTemp*(dbUpper-dbLow);
}
//返回浮点数四舍五入取整后的浮点数
double ROUND(double dbA)
{
return (double)((int)(dbA+0.5));
}
//=====================================================================
//蚂蚁类的定义和实现
//=====================================================================
//定义蚂蚁类
class CAnt
{
public:
CAnt(void);
~CAnt(void);
public:
int m_nPath[N_CITY_COUNT]; //蚂蚁走的路径
double m_dbPathLength; //蚂蚁走过的路径长度
int m_nAllowedCity[N_CITY_COUNT]; //没去过的城市
int m_nCurCityNo; //当前所在城市编号
int m_nMovedCityCount; //已经去过的城市数量
public:
int ChooseNextCity(); //选择下一个城市
void Init(); //初始化
void Move(); //蚂蚁在城市间移动
void Search(); //搜索路径
void CalPathLength(); //计算蚂蚁走过的路径长度
};
//构造函数
CAnt::CAnt(void)
{
}
//析构函数
CAnt::~CAnt(void)
{
}
//初始化函数,蚂蚁搜索前调用
void CAnt::Init()
{
for (int i=0;i<N_CITY_COUNT;i++)
{
m_nAllowedCity[i]=1; //设置全部城市为没有去过
m_nPath[i]=0; //蚂蚁走的路径全部设置为0
}
//蚂蚁走过的路径长度设置为0
m_dbPathLength=0.0;
//随机选择一个出发城市
m_nCurCityNo=rnd(0,N_CITY_COUNT);
//把出发城市保存入路径数组中
m_nPath[0]=m_nCurCityNo;
//标识出发城市为已经去过了
m_nAllowedCity[m_nCurCityNo]=0;
//已经去过的城市数量设置为1
m_nMovedCityCount=1;
}
//选择下一个城市
//返回值 为城市编号
int CAnt::ChooseNextCity()
{
int nSelectedCity=-1; //返回结果,先暂时把其设置为-1
//==============================================================================
//计算当前城市和没去过的城市之间的信息素总和
double dbTotal=0.0;
double prob[N_CITY_COUNT]; //保存各个城市被选中的概率
for (int i=0;i<N_CITY_COUNT;i++)
{
if (m_nAllowedCity[i] == 1) //城市没去过
{
//该城市和当前城市间的信息素
prob[i]=pow(g_Trial[m_nCurCityNo][i],ALPHA)*pow(1.0/g_Distance[m_nCurCityNo][i],BETA);
dbTotal=dbTotal+prob[i]; //累加信息素,得到总和
}
else //如果城市去过了,则其被选中的概率值为0
{
prob[i]=0.0;
}
}
//==============================================================================
//进行轮盘选择
double dbTemp=0.0;
if (dbTotal > 0.0) //总的信息素值大于0
{
dbTemp=rnd(0.0,dbTotal); //取一个随机数
for (int i=0;i<N_CITY_COUNT;i++)
{
if (m_nAllowedCity[i] == 1) //城市没去过
{
printf("dbtemp=%f-i=%d",dbTemp,i);system("pause");
dbTemp=dbTemp-prob[i]; //这个操作相当于转动轮盘,如果对轮盘选择不熟悉,仔细考虑一下
if (dbTemp < 0.0) //轮盘停止转动,记下城市编号,直接跳出循环
{
nSelectedCity=i;
break;
}
}
}
if(dbTemp>0){printf("dbtemp=%d",dbTemp);system("pause");}
}
//==============================================================================
//如果城市间的信息素非常小 ( 小到比double能够表示的最小的数字还要小 )
//那么由于浮点运算的误差原因,上面计算的概率总和可能为0
//会出现经过上述操作,没有城市被选择出来
//出现这种情况,就把第一个没去过的城市作为返回结果
if (nSelectedCity == -1)
{
for (int i=0;i<N_CITY_COUNT;i++)
{
if (m_nAllowedCity[i] == 1) //城市没去过
{
nSelectedCity=i;
break;
}
}
}
//==============================================================================
//返回结果,就是城市的编号
return nSelectedCity;
}
//蚂蚁在城市间移动
void CAnt::Move()
{
int nCityNo=ChooseNextCity(); //选择下一个城市
m_nPath[m_nMovedCityCount]=nCityNo; //保存蚂蚁走的路径
m_nAllowedCity[nCityNo]=0;//把这个城市设置成已经去过了
m_nCurCityNo=nCityNo; //改变当前所在城市为选择的城市
m_nMovedCityCount++; //已经去过的城市数量加1
}
//蚂蚁进行搜索一次
void CAnt::Search()
{
Init(); //蚂蚁搜索前,先初始化
//如果蚂蚁去过的城市数量小于城市数量,就继续移动
while (m_nMovedCityCount < N_CITY_COUNT)
{
Move();
}
//完成搜索后计算走过的路径长度
CalPathLength();
}
//计算蚂蚁走过的路径长度
void CAnt::CalPathLength()
{
m_dbPathLength=0.0; //先把路径长度置0
int m=0;
int n=0;
for (int i=1;i<N_CITY_COUNT;i++)
{
m=m_nPath[i];
n=m_nPath[i-1];
m_dbPathLength=m_dbPathLength+g_Distance[m][n];
}
//加上从最后城市返回出发城市的距离
n=m_nPath[0];
m_dbPathLength=m_dbPathLength+g_Distance[m][n];
}
//=====================================================================
//TSP类的定义和实现
//=====================================================================
//tsp类
class CTsp
{
public:
CTsp(void);
~CTsp(void);
public:
CAnt m_cAntAry[N_ANT_COUNT]; //蚂蚁数组
CAnt m_cBestAnt; //定义一个蚂蚁变量,用来保存搜索过程中的最优结果
//该蚂蚁不参与搜索,只是用来保存最优结果
public:
//初始化数据
void InitData();
//开始搜索
void Search();
//更新环境信息素
void UpdateTrial();
};
//构造函数
CTsp::CTsp(void)
{
}
CTsp::~CTsp(void)
{
}
//初始化数据
void CTsp::InitData()
{
//先把最优蚂蚁的路径长度设置成一个很大的值
m_cBestAnt.m_dbPathLength=DB_MAX;
//计算两两城市间距离
double dbTemp=0.0;
for (int i=0;i<N_CITY_COUNT;i++)
{
for (int j=0;j<N_CITY_COUNT;j++)
{
dbTemp=(x_Ary[i]-x_Ary[j])*(x_Ary[i]-x_Ary[j])+(y_Ary[i]-y_Ary[j])*(y_Ary[i]-y_Ary[j]);
dbTemp=pow(dbTemp,0.5);
//城市间距离四舍五入取整,eil51.tsp的最短路径426是距离按四舍五入取整后得到的。
g_Distance[i][j]=ROUND(dbTemp);
}
}
//初始化环境信息素,先把城市间的信息素设置成一样
//这里设置成1.0,设置成多少对结果影响不是太大,对算法收敛速度有些影响
for (int i=0;i<N_CITY_COUNT;i++)
{
for (int j=0;j<N_CITY_COUNT;j++)
{
g_Trial[i][j]=1.0;
}
}
}
//更新环境信息素
void CTsp::UpdateTrial()
{
//临时数组,保存各只蚂蚁在两两城市间新留下的信息素
double dbTempAry[N_CITY_COUNT][N_CITY_COUNT];
memset(dbTempAry,0,sizeof(dbTempAry)); //先全部设置为0
//计算新增加的信息素,保存到临时数组里
int m=0;
int n=0;
for (int i=0;i<N_ANT_COUNT;i++) //计算每只蚂蚁留下的信息素
{
for (int j=1;j<N_CITY_COUNT;j++)
{
m=m_cAntAry[i].m_nPath[j];
n=m_cAntAry[i].m_nPath[j-1];
dbTempAry[n][m]=dbTempAry[n][m]+DBQ/m_cAntAry[i].m_dbPathLength;
dbTempAry[m][n]=dbTempAry[n][m];
}
//最后城市和开始城市之间的信息素
n=m_cAntAry[i].m_nPath[0];
dbTempAry[n][m]=dbTempAry[n][m]+DBQ/m_cAntAry[i].m_dbPathLength;
dbTempAry[m][n]=dbTempAry[n][m];
}
//==================================================================
//更新环境信息素
for (int i=0;i<N_CITY_COUNT;i++)
{
for (int j=0;j<N_CITY_COUNT;j++)
{
g_Trial[i][j]=g_Trial[i][j]*ROU+dbTempAry[i][j]; //最新的环境信息素 = 留存的信息素 + 新留下的信息素
}
}
}
void CTsp::Search()
{
char cBuf[256]; //打印信息用
//在迭代次数内进行循环
for (int i=0;i<N_IT_COUNT;i++)
{
//每只蚂蚁搜索一遍
for (int j=0;j<N_ANT_COUNT;j++)
{
m_cAntAry[j].Search();
}
//保存最佳结果
for (int j=0;j<N_ANT_COUNT;j++)
{
if (m_cAntAry[j].m_dbPathLength < m_cBestAnt.m_dbPathLength)
{
m_cBestAnt=m_cAntAry[j];
}
}
//更新环境信息素
UpdateTrial();
//输出目前为止找到的最优路径的长度
sprintf(cBuf,"\n[%d] %.0f",i+1,m_cBestAnt.m_dbPathLength);
printf(cBuf);
}
}
//=====================================================================
//主程序
//=====================================================================
int main()
{
//用当前时间点初始化随机种子,防止每次运行的结果都相同
time_t tm;
time(&tm);
unsigned int nSeed=(unsigned int)tm;
srand(nSeed);
//开始搜索
CTsp tsp;
tsp.InitData(); //初始化
tsp.Search(); //开始搜索
//输出结果
printf("\nThe best tour is :\n");
char cBuf[128];
for (int i=0;i<N_CITY_COUNT;i++)
{
sprintf(cBuf,"%02d ",tsp.m_cBestAnt.m_nPath[i]+1);
if (i % 20 == 0)
{
printf("\n");
}
printf(cBuf);
}
printf("\n\nPress any key to exit!");
getchar();
return 0;
}

转载:http://www.cnblogs.com/sky-view/p/3281186.html

时间: 2024-12-25 23:38:27

基本蚁群算法的相关文章

蚁群算法求解迷宫最优路径问题

本段程序的基本思想是利用蚁群算法中的蚁周模型,来对全局的迷宫图进行信息素的跟新 和为每一只蚂蚁选择下一个方格. 一共会进行RcMax = 2000轮模拟(理论上模拟的次数越多结果 会越接近真实值),而在每一轮中会排除 M = 10只蚂蚁进行探路.同时在算法的回溯思想上采用的 是栈的数据结构来实现的.当栈最终为空时则表示无解.但同时这段程序的一缺点就是:由于我没在 算法中对每一轮的每只探路蚂蚁采用多线程的模式,所以整体的运行效率还不是很高.如读者有好的 思想或建议,请留言. #include<io

智能算法---蚁群算法

智能算法---蚁群算法 1 蚁群算法及其基本思想 蚁群算法是一种智能优化算法,通过蚁群优化求解复杂问题,ACO在离散优化问题方面有比较好的优越性. 基本思想(以旅行商问题为例) 设置多只蚂蚁,分头并行搜索. 每只蚂蚁完成一次周游后,在行进的路上释放信息素,信息素量与解的质量成正比. 蚂蚁路径的选择根据信息素强度大小(初始信息素量设为相等),同时考虑两点之间的距离,采用随机的局部搜索策略.这使得距离较       短的边,其上的信息素量较大,后来的蚂蚁选择该边的概率也较大. 每只蚂蚁只能走合法路线

蚁群算法

今天真机调试的时候莫名其妙遇到了这样的一个问题: This product type must be built using a provisioning profile, however no provisioning profile matching both the identity "iPhone Developer" and the bundle identifier..... 具体如下图所示: 十分蛋疼, 发现不管是从网上下的demo, 还是自己的过程.凡事真机测试的时候都

基于自适应蚁群算法的无人飞行器航迹规划

为求解无人飞行器航迹规划问题,提出自适应蚁群算法,区别于标准蚁群算法的全部搜索模式,该算法采用局部搜索模式.首先根据起始节点与目标节点的相对位置 关系选择相应的搜索模式,然后计算各个待选节点的转移概率,最后按照轮盘赌规则选择下一个节点.仿真结果表明,自适应蚁群算法具有搜寻节点数少.速度快等 优点,在降低了航迹代价的同时,减小了计算时间.此外,自适应蚁群算法可以避免奇异航迹段的出现,从而保证所获的航迹实际可飞,表明所提算法整体性能明显 较标准蚁群算法优异. 此资料( 基于自适应蚁群算法的无人飞行器

初识遗传算法 蚁群算法

今天看这篇文章 Link 里面提到遗传算法.蚁群算法等. 遗传算法看这一篇: https://www.zealseeker.com/archives/python-genetic-algorithm/ 这篇文章比较了几种寻找最大值的方法: http://blog.csdn.net/emiyasstar__/article/details/6938608 爬山法.模拟退火和遗传算法 是解决寻找最大值问题的几种常见的算法 http://www.cnblogs.com/Leo_wl/p/5665715

蚁群算法解决TSP问题

一.论述 1.算法来源 蚁群算法的基本原理来源于自然界蚂蚁觅食的最短路径原理,根据昆虫学家的观察,发现自然界的蚂蚁虽然视觉不发达,但它可以在没有任何提示的情况下找到从食物源到巢穴的最短路径,并且能在环境发生变化(如原有路径上有了障碍物)后,自适应地搜索新的最佳路径. 2.单个蚂蚁寻找路径 正反馈: 单个的蚂蚁为了避免自己迷路,它在爬行时,同时也会释放一种特殊的分泌物--信息素(Pheromone),而且它也能觉察到一定范围内的其它蚂蚁所分泌的信息素,并由此影响它自己的行为.当一条路上的信息素越来

蚁群算法和简要matlab来源

1 蚁群算法原理 从1991由意大利学者 M. Dorigo,V. Maniezzo 和 A. Colorni 通过模拟蚁群觅食行为提出了一种基于群体的模拟进化算法--蚁群优化.极大关注,蚁群算法的特点: ① 其原理是一种正反馈机制或称增强型学习系统; 它通过[最优路径上蚂蚁数量的添加→信息素强度添加→后来蚂蚁选择概率增大→最优路径上蚂蚁数量更大添加]达到终于收敛于最优路径上L ② 它是一种通用型随机优化方法, 它吸收了蚂蚁的行为特(内在搜索机制) , 它是使用人工蚂蚁仿真(也称蚂蚁系统) 来求

蚁群算法求解TSP问题

蚁群算法的第一个算法就是蚂蚁系统,而蚂蚁系统有三种基本模型分别是 蚁周模型.蚁密模型.蚁量模型.三种模型的实现大致相同,主要区别是在信息素 的更新方式上.在用蚂蚁系统解决T SP问题时,蚁量模型和蚁密模型是蚂蚁在构建 一条合法路径的过程中进行信息素的更新的,当蚂蚁走过一条边之后,就对该边进 行信息素的更新,即为局部更新方式.而蚁周模型是在所有蚂蚁都构建了一条合 法路径之后才对各边进行信息素更新的,也即全局更新方式. 并且这三种模型中蚂蚁在自己所走过的路线上释放的信息素的量也是有所 不同的,在蚁密

ACS蚁群算法求解对称TSP旅行商问题的JavaScript实现

本来以为在了解蚁群算法的基础上实现这道奇怪的算法题并不难,结果实际上大相径庭啊.做了近三天时间,才改成现在这能勉强拿的出手的模样.由于公式都是图片,暂且以截图代替那部分内容吧,mark一记. 蚁群算法解TSP问题的javascript实现 目录(又是神奇的手动目录..) 1 蚁群算法 (1)        蚁群AS算法简介 (2)        蚁群AS算法过程 (3)        蚁群AS算法TSP问题应用 (4)        蚁群算法应用于TSP步骤 2 蚁群系统(Ant Colony