现代优化算法

启发式算法包括了:禁忌搜索,模拟退火,遗传算法,人工神经网络。目标:求NP-hard组合优化问题的全局最优解。解决复杂优化问题的蚁群算法,根据实际问题产生的解空间分解、解空间限制,还有对多个启发式算法的合成的集成算法。

主要用于解决组合优化问题:TSP,QAP,JSP

1 模拟退化算法

1.1 算法简介

该算法主要思想来自于材料的统计力学,高温条件下粒子的能量较高,可以自由运动和重新排列。而低温条件下,粒子能量较低。如果从高温开始,缓慢降温(退火),粒子就可以在每个温度下达到热平衡。系统完全冷却时,最终形成处于低能状态的晶体。

退火算法用下列数学模型描述退火过程。

假设材料在状态$i$之下的能量为$E(i)$,则材料在温度$T$时从状态$i$进入状态$j$遵循以下规律:
(1)如果$E(j) \le E(i)$,接受该状态被转换

(2)如果$E(j) \gt E(i)$,则状态转换以如下概率被接受:

$$ e^{\frac{E(i)-E(j)}{KT}} $$

其中$K$为玻尔兹曼常数,$T$是材料温度

在某个特定的温度下,经过充分转换之后,材料达到热平衡,这时候材料处于状态$i$的概率满足玻尔兹曼分布:

$$ P_{T}(x=i)=\frac{e^-{\frac{E(i)}{KT}}}{\sum_{j \in S}e^-{\frac{E(j)}{KT}}} $$

其中$x$表示材料当前状态的随机变量,$S$表示状态空间集合。

显然有:

$$ \lim_{T \to \infty}\frac{e^-{\frac{E(i)}{KT}}}{\sum_{j \in S}e^-{\frac{E(j)}{KT}}}=\frac{1}{|S|} $$

其中$|S|$表示集合$S$中状态的数量。这表明所有状态在高温下具有相同的概率。而当温度下降时,

$$ \lim_{T \to 0}\frac{e^-{\frac{E(i)-E_{min}}{KT}}}{\sum_{j \in S}e^-{\frac{E(j)-E_{min}}{KT}}}=\lim_{T \to 0}\frac{e^-{\frac{E(i)-E_{min}}{KT}}}{\sum_{j \in S_{min}}e^-{\frac{E(j)-E_{min}}{KT}}+\sum_{j \notin S_{min}}e^-{\frac{E(j)-E_{min}}{KT}}}\\ =\lim_{T \to 0}\frac{e^-{\frac{E(i)-E_{min}}{KT}}}{\sum_{j \in S_{min}}e^-{\frac{E(j)-E_{min}}{KT}}}=\begin{cases} \frac{1}{|S_{min}|} \quad 若i \in S_{min}\\ 0 \quad 其它 \end{cases} $$

其中$E_{min}=\min_{j \in S}E(j)$且$S_{min}=\left\{i|E(i)=E_{min}\right\}$

上式表明当温度降至很低时,材料会以很大概率进入最小能量状态。

1.2 模拟退火寻优方法:

解是不断由退火生成的,但是是以概率来确定的。并且是一个马尔可夫过程,转移概率服从均匀分布。不断地进行状态转移,直到温度降低为0。而根据理论分析,模拟退火算法可以找到全局最优解。

要注意的问题有:
(1),理论上,降温过程要足够缓慢,使得在每个温度下达到热平衡,才能不至于跳过任何一个可能的解。不过会导致算法比较慢,正常选用的时候都需要折衷。

(2),要确定在每一温度下状态的结束准则。实际操作可以考虑当连续$m$次的转换过程没有使状态发生改变的时候,结束该温度下的状态转换。 最终温度的确定可以提前定为一个较小的值$T_{e}$,或连续几个温度下转换过程没有使状态发生变化算法就结束。

(3),选择初始温度和确定某个可行解的邻域的方法也要恰当。

1.3 举个例子

例子:已经知道敌方的100个目标的经纬度(具体数据可以找我索取)

我方有一个基地,经度和纬度为(70,40)。假设我方飞机的速度为 1000 公里/小时。我方派一架飞机从基地出发,侦察完敌方所有目标,再返回原来的基地。在敌方每一目标点的侦察时间不计,求该架飞机所花费的时间(假设我方飞机巡航时间可以充分长)。

这是一个旅行商问题。我们依次给基地编号为 1,敌方目标依次编号为 2, 3,…,101, 最后我方基地再重复编号为 102(这样便于程序中计算)。 距离矩阵$D=(d_{ij})_{102*102}$,其中$d_{ij}$表示$i,j$两点的距离,$i,j=1,2,\cdots,102$,这里$D$为实对称矩阵。则问题变成了从点1出发,走遍中间的所有点,到达点120的一个最短路径。

但是由于给定的是地理坐标,我们要转化为求两点之间的实际距离。设$A,B$两点的地理坐标为$(x_1,y_1),(x_2,y_2)$,过$A,B$两点的 大圆的劣弧长即为两点的实际距离。以地心为坐标原点$O$,以赤道平面为$XOY$平面,以0度经线圈所在的平面为$XOZ$平面建立三维直角坐标系。则$A,B$两点的直角坐标分别为:

$$ A(Rcosx_1cosy_1,Rsinx_1cosy_1,Rsiny_1)\\ B(Rcosx_2cosy_2,Rsinx_2cosy_2,Rsiny_2)\\ $$

其中$R=6370$为地球半径。

$A,B$两点的实际距离

$$ d=Rarccos(\frac{\vec{OA}{\cdot}\vec{OB}}{|\vec{OA}|{\cdot}|\vec{OB}|}) $$

化简得到:

$$ d=Rarccos[cos(x_1-x_2)cosy_1cosy_2+siny_1siny_2]。 $$

1.4 模拟退火算法描述如下:

(1)解空间

解空间$S$可表为$\left\{1,2,\cdots,101,102\right\}$的所有固定起点和重点的循环排列集合,即$S=\left\{\pi_1,\cdots,\pi_{102}|\pi_1=1,(\pi_2,\cdots,\pi_{101})\right\}$为$\left\{2,3,\cdots,101\right\}$的循环排列,$\pi_{102}=102$,其中每一个循环表示侦察100个目标的一个回路,$\pi_i=j$表示在第$i$次侦察$j$点,初始解可选为(1,2,...,102)

(2)目标函数

此时的目标函数为侦察所有目标的路径长度或者称为代价函数,我们要求:

$$ \min f(\pi_1,\pi_2,\cdots,\pi_{102})=\sum^101_{i=1}d_{\pi_i\pi_{i+1}}\\ $$

而一次迭代由下列三步构成;

(3)新解的产生

2变换法:

任选序号$u,v(u \lt v)$交换$u$与$v$之间的顺序,此时的新路径为:

$$ \pi_1\cdots\pi_{u-1}\pi_v\pi_{v+1}\cdots\pi_{u+1}\pi_u\pi_{v+1}\cdots\pi_{102}\\ $$

(4)代价函数差

这里采用2变换法得到的路径差表示为:

$$ \Delta f=(d_{\pi_{u-1}\pi_v}+d_{\pi_u\pi_{v+1}})-(d_{\pi_{u-1}\pi_u}+d_{\pi_v\pi_{v+1}}) $$

(5)接受准则

$$ P=\begin{cases} 1\quad \Delta f \lt0\\ exp(-\Delta f/T) \quad \Delta f \ge 0\\ \end{cases} $$

如果$\Delta f \lt 0$则接受新的路径,否则以概率$exp(-\Delta f/T)$接受新的路径,即若$exp(-\Delta f/T)$大于0到1之间的随机数则接受。

(6)降温

利用选定的降温系数$\alpha$进行降温即:$T \gets \alpha{T}$,得到新的温度,这里我们取$\alpha=0.999$

(7)结束条件

用选定的终止温度$e=10^{-30}$,判断退火过程是否结束。若$T \lt e$,算法结束,输出当前状态。

1.5 Matlab算法程序

matlab程序代码如下:

clc,clear;
load sj.txt %加载敌方 100 个目标的数据, 数据按照表格中的位置保存在纯文本文件 sj.txt 中,为25*8的矩阵格式
x=sj(:,1:2:8);x=x(:);  %取1到8列中步长为2的列数,并且转换为列向量。(原本为25*4的矩阵格式)
y=sj(:,2:2:8);y=y(:);  %取2到8列中步长为2的列数,并且转换为列向量。
sj=[x y];              %转换为矩阵100*2的经纬度矩阵
d1=[70,40];            %我方基地的经纬度
sj=[d1;sj;d1];         %加入我方基地,从基地绕一圈再回到基地。所以102*2矩阵
sj=sj*pi/180;          %转换为弧度制
%距离矩阵 d
d=zeros(102);          %给出一个基本的零矩阵初始化以存储距离
for i=1:101             %迭代行数
 for j=i+1:102          %迭代列数
 temp=cos(sj(i,1)-sj(j,1))*cos(sj(i,2))*cos(sj(j,2))+sin(sj(i,2))*sin(sj(j,2));   %两点间距离公式(三维)
 d(i,j)=6370*acos(temp);   %地球半径6370
 end
end
d=d+d';             %搞出实对称矩阵,两两基地之间的距离
S0=[];Sum=inf;      %初始化走过的结点,初始化路径长度
rand('state',sum(clock));   %根据当前时间设定初始状态随机数器
for j=1:1000
 S=[1 1+randperm(100),102];  %s是一维数组,第一位是1,中间是2到101的随机序列,最后一位是102
 temp=0;                     %临时变量设为0
 for i=1:101             
 temp=temp+d(S(i),S(i+1));   %临时变量是距离,不断遍历这些飞机飞过的点
 end
 if temp<Sum                 %在循环过程中,如果临时距离小于Sum,则下面两个语句执行,也就是找到飞过这些路线的最短距离。           
 S0=S;Sum=temp;
 end
end
e=0.1^30;L=20000;at=0.999;T=1;   %退火参数
%退火过程
for k=1:L   %我tm迭代个2w次
 %产生新解
c=2+floor(100*rand(1,2));  %产生102之间的两个数字——经纬度
c=sort(c);                 %进行升序排列
c1=c(1);c2=c(2);           %取出经纬度
 %计算代价函数(也就是路径差)
 df=d(S0(c1-1),S0(c2))+d(S0(c1),S0(c2+1))-d(S0(c1-1),S0(c1))-d(S0(c2),S0(c2+1));
 %接受准则
 if df<0            %代价函数差接受路径
 S0=[S0(1:c1-1),S0(c2:-1:c1),S0(c2+1:102)];
 Sum=Sum+df;        %更正路径长度
 elseif exp(-df/T)>rand(1)  %按照概率接受准则接受新路径
 S0=[S0(1:c1-1),S0(c2:-1:c1),S0(c2+1:102)];   %接受路径
 Sum=Sum+df;        %更正路径长度
 end
 T=T*at;     %退火计算得到新的温度
 if T<e      %直到冷却
 break;
 end
end
 % 输出巡航路径及路径长度
S0,Sum

本质上是通过用随机序列爆算出最小长度,然后再通过退火算法的2代换,用随机序列再次计算代价函数差,然后根据温度退火决定后面的2代换次数,最后冷却输出最小的距离长度。

Last modification:August 21st, 2019 at 09:26 pm
如果觉得我的文章对你有用,请随意赞赏