- #include<iostream>
- #include<string>
- #include<math.h>
- #include<cstdlib>
- using namespace std;
- // ******************************************************************************************
- /*
- 模拟退火算法解决10城市的TSP问题
- (1) 初始化:初始温度T(充分大),初始解状态S(是算法迭代的起点), 每个T值的迭代次数L
- (2) 对k=1,……,L做第(3)至第6步:
- (3) 产生新解S′
- (4) 计算增量Δt′=C(S′)-C(S),其中C(S)为评价函数
- (5) 若Δt′<0则接受S′作为新的当前解,否则以概率exp(-Δt′/T)接受S′作为新的当前解.
- (6) 如果满足终止条件则输出当前解作为最优解,结束程序。
- 终止条件通常取为连续若干个新解都没有被接受时终止算法。
- (7) T逐渐减少,且T->0,然后转第2步。
- baixzh SYSU 2008-11-19
- */
- // ******************************************************************************************
- int i;int j;
- struct city//城市节点 坐标表示
- {
- double x;
- double y;
- city();
- };
- city::city ()
- {
- x=0.0;
- y=0.0;
- }
- city c_t[10];//10个城市的tsp问题
- double pos[20]=//初始城市坐标数据
- {
- 0.400, 0.4439,//代表x,y
- 0.2439, 0.1463,
- 0.1707, 0.2293,
- 0.2293, 0.7610,
- 0.5171, 0.9414,
- 0.8732, 0.6536,
- 0.6878, 0.5219,
- 0.8488, 0.3609,
- 0.6683, 0.2536,
- 0.6195, 0.2634
- };
- double dis[10][10];//城市距离矩阵
- int state[10]={7,8,9,1,5,0,6,2,4,3};//给出初始路径
- int s1[10],s2[10];//s1原始路径 s2为s1生成的临近路径
- double result1,result2;//原路径长度 临近路径长度
- void xch(int state[10])//生成临近路径并且计算长度,保存原路径
- {
- result1=result2=0.0;
- for(i=0;i<10;i++)
- {
- s1[i]=s2[i]=state[i];
- }
- for(i=0;i<9;i++)
- {
- result1=result1+dis[s1[i]][s1[i+1]];
- }
- result1=result1+dis[s1[0]][s1[9]];
- //s1以前的s2改变后的
- int k1=rand()%10;int k2=rand()%10;
- if(k1==k2)
- {
- k2=(k1+2)%10;
- }
- swap(s2[k1],s2[k2]);
- for(i=0;i<9;i++)
- {
- result2=result2+dis[s2[i]][s2[i+1]];
- }
- result2=result2+dis[s2[0]][s2[9]];
- //最后要返回出发城市
- }
- int main()
- {
- for(i=0;i<10;i++)
- {
- c_t[i].x =pos[2*i];
- c_t[i].y =pos[2*i+1];
- }
- //城市节点初始化
- memset(dis,0.0,sizeof(dis));
- for(i=0;i<10;i++)
- for(j=0;j<10;j++)
- {
- dis[i][j]=sqrt(pow((c_t[i].x -c_t[j].x),2) +pow((c_t[i].y-c_t[j].y),2)) ;
- }
- //距离矩阵初始化
- double tmp=1000.0;
- int loop_1=1;//外循环计数
- int loop_2=0;//内循环计数
- while(1)
- {
- loop_2=0;
- while(1)
- {
- if(loop_2>tmp*3)//内循环结束条件
- {
- break;
- }
- xch(state);
- loop_2++;
- if(result2<result1)
- {
- for(j=0;j<10;j++)
- {
- state[j]=s2[j];
- }
- //如果生成路径长度小于原始路径则替换
- }
- else
- {
- double d=(result2-result1);
- double e=exp(-d/(0.0001*tmp));
- double r=rand()%100;
- double k=r/100.0;
- if(e>k)
- {
- for(j=0;j<10;j++)
- {
- state[j]=s2[j];
- }
- //如果生成路径长度大于初始路径长度//但是概率e>rand(0,1)也接受新路径
- }
- else
- {
- for(j=0;j<10;j++)
- {
- state[j]=s1[j];
- }
- }//否则不做替换
- }
- }
- //输出每次内部循环结束后的路径
- xch(state);
- cout<<"第"<<loop_1<<"次降温 "<<"温度为"<<tmp<<" 结果为 :"<<endl;
- cout<<result1<<" ";
- for(j=0;j<9;j++)
- {
- cout<<char('A'+state[j])<<"--";
- }
- cout<<char('A'+state[9])<<endl;
- tmp=tmp*0.95;//温度按照比例下降
- loop_1++;
- if(tmp<1)//外循环结束条件
- {
- break;
- }
- }
- return 0;
- }
模拟退火算法 解决旅行商(TSP)问题
最新推荐文章于 2023-11-29 01:15:00 发布