1.局部搜索算法
a.定义
step1:选定一个初始可行解:x0;记录当前最优解:xbest = x0,T = N( xbest )。
step2:当T \ ( xbest ) = 空集时,或者满足其他停止运算准则时,输出计算结果,停止运算;否则,从T中选一集合S,得到S中的最好接xnow;若f ( xnow ) < f ( xbest ),则xbest = xnow,T = N ( xbest );否则,T : = T \ S;重复step2。
b.方法1--全邻域搜索(以五城市对称TSP问题为例)
一、图:
二、算法描述(以五城市对称TSP问题为例):
初始:xbest = (A,B,C,D,E),f( xbest )=45,本例中,定义邻域映射为对换2个城市的位置。S为N( xbest )全集。
进入循环:
循环1:N(xbest)={(ABCDE),(ACBDE),(ADCBE),(AECDB),(ABDCE),(ABEDC),(ABCED)},对应目标函数为f(x)={45, 43, 45, 60, 60, 59, 44}
判定条件:xbest=(ACBDE),f(x)=43。xbest与初始状态不同,N(xbest) \ (xbest) != 空集
循环2:N(xbest)={(ACBDE),(ABCDE),(ADBCE),(AEBDC),(ACDBE),(ACEDB),(ACBED)},对应目标函数为f(x)={43, 45, 44, 59, 59, 58, 43}
判定条件:xbest=(ACBDE),f(x)=43。xbest与初始状态相同,N(xbest)与循环1相同,N(xbest) \ (xbest) = 空集,跳出循环
得解xbest=(ACBDE),f(xbest)=43。
三、代码:
void localsearchWNS(const vector< vector<int> > &v,vector<int> &x,int &costbest,int firstcity) { swap(x[0],x[firstcity]); costbest=countDis(x,v);//countDis用于计算花费,代码在此不再贴出 vector<int> tempx=x; int num=x.size(); while(true) { int min=costbest; for(int i=1;i<num-1;i++) { for(int j=i+1;j<num;j++) { swap(x[i],x[j]); int temp=countDis(x,v); if(temp<min) { min=temp; tempx=x; } swap(x[i],x[j]); } } if(min==costbest) { break; } costbest=min; x=tempx; } }
四、实验:
实验所得,当n<9(比较小的时候),所求与全局最优解相同(回溯求得),在n>10之后,开始有偏离,并且偏离程度不可预测。除起点A外,解空间树共4!=24种情况,以上搜索只搜索了12种,故局部搜索算法<全邻域搜索>并没有搜索完整棵解空间树,求得也不是全局最优解,而是局部最优解。用局部最优解代替全局最优解。
c.方法2--一步随机搜索
一、算法描述:
初始:xbest = (A,B,C,D,E),f( xbest )=45,本例中,定义邻域映射为对换2个城市的位置。
进入循环:
循环x:从N(xbest)中随机选择一点xnow,如果f(xnow)<f(xbest),则xbest=xnow,且重新构建N(xbest);如果f(xnow)>=f(xbest),则从N(xbest)中移除点xnow,继续循环
判定条件:N(xbest) = 空集,跳出循环
得解
二、代码: