ACO蚁群算法全局路径规划

作者:赤戟
链接:https://www.zhihu.com/question/20207322/answer/27387066
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

蚁群算法是一种近似算法,它不是用来解决已存在精确有效算法的问题的,而是用来解决至今没有找到精确的有效算法的问题的,比如旅行商问题(TSP)。

旅行商问题也可以说是求“最短路径”,但它是求一个完全图的最小哈密顿圈,这个问题至今未找到多项式时间算法,属于NPC问题,也就是说,当问题规模稍大一点,现有的精确算法的运算量就会急剧增加
 

蚁群算法的优势在哪里?

要明白这个问题,就要搞清楚算法是用来干什么的?

算法就是用来解决各类问题的,比如题主问题中的最短路径问题。

在数学领域,根据问题本身的复杂度是有分类的。

简单来说,问题分为P问题,NP问题,NPC问题,NP-hard问题。

P是多项式这个单词的首写字母,即Polynomial,【这里指多项式时间】

P问题意为 总能找到相应的经典算法 在多项式时间 里面得出最优解。

NP问题意为 不能确定是否能找到相应算法 能够在多项式时间内 得出最优解。

NPC问题可以理解成NP问题中最难(复杂度最高)的问题,也就是说很难找到相应算法 能够在多项式时间内得出最优解。

NP-hard问题可以简单理解成找不到相应算法 能够在多项式时间内得出最优解。

所有对NP问题的研究都集中在一个问题上,即究竟是否有P=NP?通常所谓的“NP问题”,其实就一句话:证明或推翻P=NP。目前进度不理想,不多说了。四者之间的关系,有兴趣看图,没兴趣跳过,不影响。

搞清楚问题的分类就很简单了,这些问题影响了计算机算法的研究方向。

简单来说就是,传统的经典算法能够解决P类问题,而NP问题,特别是NPC问题,则束手无策,于是科学家们开始想办法了,既然不能在多项式时间里得出一个最优解,那么咱们得一个较优解吧,用先验的经验知识作为启发算子,于是启发式算法诞生了,但启发式算法只能针对特定问题(比如,prime算法和kruskal算法都是经典启发式算法,在最小生成树领域比较好的效果),启发式算法不适合跨领域,但NP问题又如此之多,怎么办,于是各种仿生学理论开始引入计算机的算法领域,诞生了所谓的蚁群,粒子群,遗传,神经网络算法这些统称智能优化算法(元启发式算法)的来求较优解。

算法介绍:

 蚁群算法(Ant Colony Algorithm,ACA)于1992年在首次提出,‘该算法模拟了自然界中蚂蚁的觅食行为。

蚂蚁在寻找食物源时,会在其经过的路径上释放一种信息素,并能够感知其它蚂蚁释放的信息素。信息素浓度的大小表征路径的远近,信息素浓度越高,表示对应的路径距离越短。

通常,蚂蚁会以较大的概率优先选择信息素浓度较高的路径,并∶释放一定量的信息素,以增强该条路径上的信息素浓度,这样,会形成一个正反馈。最终,蚂蚁能够找到一条从巢穴到食物源的i最佳路径,即距离最短。

算法思想:
用蚂蚁的行走路径表示待优化问题的可行解,整个蚂蚁群体的所有路径构成待优化问题的解空间。
路径较短的蚂蚁释放的信息素量较多,随着时间的推进,较短的路径上累积的信息素浓度逐渐增高,选择该路径的蚂蚁个数也愈:来愈多。
最终,整个蚂蚁会在正反馈的作用下集中到最佳的路径上,此时对应的便是待优化问题的最优解。
但是并不是信息素浓度高就一定走那一条路线。也有几率走信息度浓度低的路线。

具体算法: 

 

参数作用:

蚂蚁数量:种群数量越多,得到的最优解就越精确,但是会有大量蚂蚁重复路过同一路径,运行时间增多。
alpha  信息素重要程度因子:alpha值过大,蚂蚁选择之前走过的路径可能性就越大,蚁群搜索路径的随机性减弱。alpha值过小,蚁群搜索范围就会减少,易陷入局部最优解。
beta 启发函数因子:beta值增大,蚁群更容易选择局部较短路径,能加快算法的运行速度,但是可能陷入局部最优解。
ruo 信息素挥发因子:当ruo很小的时候,每条路径的残留信息很多,就会反复进行搜索,运算时间增加;ruo很大的时候,会放弃搜索很多有效路径,可能会丢失最优值。
Q 信息度强度

关键代码如下:

#生成蚁群
def get_ants(self, num_city):
    for i in range(self.m):
        start = np.random.randint(num_city - 1)
        self.Table[i][0] = start
        unvisit = list([x for x in range(num_city) if x != start])
        current = start
        j = 1
        while len(unvisit) != 0:
            P = []
            # 通过信息素计算城市之间的转移概率
            for v in unvisit:
                P.append(self.Tau[current][v] ** self.alpha * self.Eta[current][v] ** self.beta)
            P_sum = sum(P)
            P = [x / P_sum for x in P]
            # 轮盘赌选择一个一个城市
            index = self.rand_choose(P)
            current = unvisit[index]
            self.Table[i][j] = current
            unvisit.remove(current)
            j += 1


# 更新信息素
def update_Tau(self):
    delta_tau = np.zeros([self.num_city, self.num_city])
    paths = self.compute_paths(self.Table)
    for i in range(self.m):
        for j in range(self.num_city - 1):
            a = self.Table[i][j]
            b = self.Table[i][j + 1]
            delta_tau[a][b] = delta_tau[a][b] + self.Q / paths[i]
        a = self.Table[i][0]
        b = self.Table[i][-1]
        delta_tau[a][b] = delta_tau[a][b] + self.Q / paths[i]
    self.Tau = (1 - self.rho) * self.Tau + delta_tau


def aco(self):
        best_lenth = math.inf  # math.inf返回浮点正无穷大
        best_path = None
        for cnt in range(self.iter_max):
            # 生成新的蚁群
            self.get_ants(self.num_city)  # out>>self.Table
            self.paths = self.compute_paths(self.Table)
            # 取该蚁群的最优解
            tmp_lenth = min(self.paths)
            tmp_path = self.Table[self.paths.index(tmp_lenth)]
            # 可视化初始的路径
            if cnt == 0:
                init_show = self.location[tmp_path]
                init_show = np.vstack([init_show, init_show[0]])
            # 更新最优解
            if tmp_lenth < best_lenth:
                best_lenth = tmp_lenth
                best_path = tmp_path
            # 更新信息素
            self.update_Tau()

            # 保存结果
            self.iter_x.append(cnt)
            self.iter_y.append(best_lenth)
            print(cnt, best_lenth)
        return best_lenth, best_path

代码讲解:

代码主要操作是先生成蚁群,让每个蚂蚁寻找路径,计算概率P并用轮盘赌方式记录每个蚂蚁的路径Table。计算每个蚂蚁的路径,取最短路径。然后更新信息素,这里主要操作时计算ΔTau,而ΔTau的选择只是针对路径而言,所以对每个蚂蚁走过都要计算一遍,最后根据挥发原理公式跟新Tau。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值