#include<time.h>
#include<stdlib.h>
#include <stdio.h>
#include <math.h>
#define Alpha 2 //启发因子
#define Beta 5 //期望启发因子
#define M 50 //蚂蚁数量
#define Q 1 //信息强度 蚂蚁走过路径的总信息素
#define Rou 0.1 //信息素挥发因子
#define NUM 30 //城市数量
City[NUM][2] = {{2,99},{4,50},{7,64},{13,40},{18,54},{18,40},{22,60},{24,42},{25,62},{25,38},
{37,84},{41,94},{41,26},{44,35},{45,21},{54,67},{54,62},{58,35},{58,69},{62,32},
{64,60},{68,58},{71,44},{71,71},{74,78},{82,7},{83,46},{83,69},{87,76},{91,38}
};
unsigned int Ant_Trace[NUM]; //一只蚂蚁走过的路径
float Ant_Info[NUM][NUM]; //一只蚂蚁走过路径的信息素
unsigned int Best_Trace[NUM]; //最短路径
float Best_Distance = 0; //最短距离
float Info[NUM][NUM], Visible[NUM][NUM]; //节点之间的信息素强度,节点之间的能见度
float AllDistance[NUM][NUM]; //两两城市之间的距离
/////////////////////////////////
// 计算两个城市之间的距离 //
/////////////////////////////////
float Calculate_CityToCityDistance(unsigned int i, unsigned int j)
{
return sqrt(pow(( abs(City[i][0] - City[j][0])), 2) + pow(( abs(City[i][1] - City[j][1])), 2));
}
/////////////////////////////////
// 由矩阵表示两两城市之间的距离//
/////////////////////////////////
void Calculate_AllDistance()
{
unsigned int i,j;
for(i = 0; i < NUM; i++)
{
for(j = i; j < NUM; j++)
{
if (i != j)
{
AllDistance[i][j] = Calculate_CityToCityDistance(i, j);
AllDistance[j][i] = AllDistance[i][j];
// printf("%f\n",AllDistance[i][j]);
}
else
AllDistance[i][j] = 0;
}
}
}
/////////////////////////////////
//获得经过NUM个城市的路径长度 //
/////////////////////////////////
float Calculate_TraceDistance(unsigned int* trace)
{
float sum = 0;
unsigned int k,i,j;
for( k = 0; k< (NUM - 1); k++)
{
i = *(trace + k);
j = *(trace + k + 1);
sum += AllDistance[i][j];
}
return sum;
}
//计算当前节点到下一节点转移的概率
float Calculate_NextNodeProbability(unsigned int i, unsigned int j)
{
if (i != j)
return (pow(Info[i][j],Alpha) * pow(Visible[i][j], Beta));
else
return 0.0;
}
//初始化路径信息素和能见度
void Init_Parameter(unsigned int initinfo)
{
unsigned int i,j;
for(i = 0; i < NUM; i++)
{
for(j = i; j < NUM; j++) //初始化路径上的信息素不能为0,否则初始概率都为0
{
Info[i][j] = initinfo;
Info[j][i] = initinfo;
if (i != j) //初始化路径能见程度
{
Visible[i][j] = 1.0 / AllDistance[i][j];
Visible[j][i] = Visible[i][j];
// printf("%f\n",Visible[i][j]);
}
else
Visible[i][j] = 0;
}
}
}
//全路径信息素更新
void Update_GlobalPathInfo()
{
unsigned int i,j;
for( i = 0; i < NUM; i++)
{
for( j = i; j < NUM; j++)
{
if( i != j)
{
// printf("%f\n",Ant_Info[i][j]);
Info[i][j] = (1.0 - Rou) * Info[i][j] + Ant_Info[i][j];
Info[j][i] =Info[i][j];
}
else
Info[i][j] = 0;
}
}
}
//计算蚂蚁走过的路径
void Calculate_AntTrace(unsigned int start_cityindex)
{
unsigned int trace_citynum = 0, allowed[NUM], current_cityindex;//走过的城市个数,允许的城市列表,当前城市序列号
unsigned int i, j;
float probability[NUM], sum = 0, rand_buf, top = 0, down = 0, Distance = 0; //到allowed[]节点的概率,probability[]概率总和,暂存随机数的值,上下限值,路径
current_cityindex = start_cityindex;
Ant_Trace[0] = current_cityindex; //记录走过的路径
for( i = 0; i < NUM; i++) //初始化allowed[]
{
allowed[i] = i;
}
while( trace_citynum < NUM) //遍历城市
{
for( i = 0; i < (NUM - trace_citynum); i++) //更新allowed[]
{
if( allowed[i] == current_cityindex)//在allowed[]去除current_cityindex元素
{
for( j = i; j < (NUM - trace_citynum - 1); j++) //将allowed[]向前移动
{
allowed[j] = allowed[j + 1];
}
break;
}
}
// for( i = 0; i < (NUM - trace_citynum - 1); i++)
// {
// printf("%d ",allowed[i]);
// }
// printf("\n",NULL);
for( i = 0; i < (NUM - trace_citynum - 1); i++) //计算各allowed[]节点的概率
{
probability[i] = Calculate_NextNodeProbability( current_cityindex, allowed[i]);
sum += probability[i];
// printf("%f ",probability[i]);
}
for( i = 0; i < (NUM - trace_citynum - 1); i++) //各allowed[]节点的概率转化成0--RAND_MAX之间的区间
{
probability[i] = ( probability[i] / sum) * RAND_MAX;
// printf("%f ",probability[i]);
}
sum = 0;
rand_buf = rand(); //生成随机数
// printf("\n%f\n",rand_buf);
for( i = 0; i < (NUM - trace_citynum - 1); i++) //查找区间
{
top += probability[i]; //更新上限值
if( down <= rand_buf && rand_buf <= top)
{
current_cityindex = allowed[i]; //更新到下一个节点
break;
}
down += probability[i]; //更新下限值
}
top = 0;
down = 0;
trace_citynum++; //更新走过的城市个数
Ant_Trace[trace_citynum] = current_cityindex; //记录走过的路径
}
Distance = Calculate_TraceDistance( Ant_Trace ); //计算路径总长度
for( i = 0; i < NUM; i++) //先清除路径的信息素
{
for( j = 0; j < NUM; j++)
{
Ant_Info[i][j] = 0;
}
}
for( i = 0; i < NUM - 1; i++) //记录走过路径的信息素
{
Ant_Info[Ant_Trace[i]][Ant_Trace[i + 1]] = (AllDistance[Ant_Trace[i]][Ant_Trace[i + 1]] / Distance) * Q;
Ant_Info[Ant_Trace[i + 1]][Ant_Trace[i]] = Ant_Info[Ant_Trace[i]][Ant_Trace[i + 1]];
// printf("%f\n",Ant_Info[Ant_Trace[i]][Ant_Trace[i + 1]]);
}
if( Best_Distance == 0.0) //首次更新最短距离
{
Best_Distance = Distance;
for( i = 0; i < NUM; i++)
Best_Trace[i] = Ant_Trace[i]; //更新最短路径
}
else
{
if( Best_Distance > Distance)
{
Best_Distance = Distance;
for( i = 0; i < NUM; i++)
Best_Trace[i] = Ant_Trace[i];
}
}
// for( i = 0; i < NUM; i++)
// {
// printf("%d ",Ant_Trace[i]);
// }
// printf("\n",NULL);
}
int main(int argc, char *argv[])
{
unsigned int i,j;
Calculate_AllDistance();
Init_Parameter(1);
srand((int)time(0));//生成随机数种子
for( i = 0; i < M; i++)
{
Calculate_AntTrace(0);
Update_GlobalPathInfo();
}
printf("Best_Trace:",NULL); //显示最佳路径
for( i = 0; i < NUM; i++)
{
printf("->%d",Best_Trace[i]);
// for( j = 0; j < NUM; j++)
// printf("AllDistance[%d][%d]=%f\n",i,j,AllDistance[i][j]);
}
printf("\ndistance:%f",Calculate_TraceDistance( Best_Trace ));
while(1);
return 0;
}
一个简单的蚁群算法
原文作者:蚁群算法
原文地址: https://blog.csdn.net/zb782387489/article/details/39118363
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/zb782387489/article/details/39118363
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。