有限级信息素蚁群算法

有限级信息素蚁群算法使用路径等级作为信息素更新的依据,相比于传统的蚁群算法,舍弃了目标函数作为信息素更新的依据这一方法。在TSP问题中,目标函数实际就是路径长度,在传统的蚁群算法中信息素更新量为Q/f(x),其中Q为某一常数,而f(x)就是目标函数值,即路径长度。而在有限级信息素蚁群算法中在这一点做出了改变。

首先给出算法的基本步骤:

步骤1:设定初始参数,初始化信息素

步骤2:按照路径选择规则构造问题的解

步骤3:按照信息素更新规则更新信息素

步骤4:判断是否达到停止条件,若满足,则停止迭代,否则跳至步骤2

有限级信息素蚁群算法主要变动就在步骤3,记《有限级信息素蚁群算法》为弧《有限级信息素蚁群算法》的级别,《有限级信息素蚁群算法》是一个单调递增函数,用于将弧的级别映射为信息素。在有限级信息素蚁群算法中,弧级别越大则弧上的信息素也就越高。《有限级信息素蚁群算法》表示路径惩罚等级,《有限级信息素蚁群算法》表示路径奖励等级。假设路径最小等级为1,路径最大等级为《有限级信息素蚁群算法》《有限级信息素蚁群算法》为当前最优解,《有限级信息素蚁群算法》为当前次迭代最优解。

步骤3可以细分为以下几步:

<1>.《有限级信息素蚁群算法》

<2>.如果《有限级信息素蚁群算法》,则《有限级信息素蚁群算法》

<3>.对于《有限级信息素蚁群算法》《有限级信息素蚁群算法》,即将当前最优解路径上的所有弧等级加《有限级信息素蚁群算法》《有限级信息素蚁群算法》

<4>.《有限级信息素蚁群算法》,保证弧等级最小为1

<5>.《有限级信息素蚁群算法》,保证弧等级最大为《有限级信息素蚁群算法》

<6>.《有限级信息素蚁群算法》《有限级信息素蚁群算法》通常选取为《有限级信息素蚁群算法》或者《有限级信息素蚁群算法》《有限级信息素蚁群算法》为每条弧上的最大信息素

有限级信息素蚁群算法代码如下:


# coding: utf-8

# In[8]:


import numpy as np
from numpy import random as rd
import os
import matplotlib.pyplot as plt
np.set_printoptions(linewidth=1000, suppress=True)


# In[2]:

# 数据下载地址:https://www.iwr.uni-heidelberg.de/groups/comopt/software/TSPLIB95/tsp/
# 将数据存放在在代码存放目录的tspdata文件夹内
with open("./tspdata/kroA100.tsp", "r", encoding="utf-8") as file:
    data = file.read()
data = np.array([p.split(" ")[1:] for p in data.split("\n")[6:-2]]).astype(np.float32)
data


# In[3]:


def calc_distance_matrix(city_position_matrix):
    """
        city_position_matrix:城市坐标矩阵,形状为N行2列,N为城市数
        返回城市间距离矩阵distance_matrix,假设城市i到城市j的距离等于城市j到城市i的距离,因此,distance_matrix为上三角矩阵
    """
    city_number = city_position_matrix.shape[0]
    distance_matrix = np.zeros(shape=[city_number, city_number], dtype=np.float32)
    for i in range(city_number):
        from_city_position = city_position_matrix[i]
        for j in range(i + 1, city_number):
            to_city_position = city_position_matrix[j]
            distance_matrix[i, j] = np.sqrt(np.sum(np.power(city_position_matrix[i] - city_position_matrix[j], 2)))
    return distance_matrix


# In[4]:


class FGP_ACO(object):
    
    def __init__(self, initial_pheromone, r_2, r_1, M, beta, max_pheromone, run_times, city_position_matrix, ant_count, initial_route_level):
        """
            initial_pheromone:每条路径上的信息素初始值
            r_2:路径奖励等级
            r_1:路径惩罚级别
            M:路径最大级别
            beta:启发信息重要程度
            max_pheromone:信息素最大值
            run_times:最大循环次数
            city_position_matrix:城市坐标矩阵,形状为N行2列,N为城市数
            ant_count:蚂蚁数量
            initial_route_leve:表示每条路径的初始级别
        """
        self.r_2 = r_2
        self.r_1 = r_1
        self.M = M
        self.beta = beta
        self.max_pheromone = max_pheromone
        self.run_times = run_times
        self.city_position_matrix = city_position_matrix
        self.ant_count = ant_count
        # 城市间距离矩阵
        self.distance_matrix = calc_distance_matrix(city_position_matrix)
        # 城市数量
        self.N = city_position_matrix.shape[0]
        # 启发信息矩阵
        self.heuristic_information_matrix = np.triu(1 / self.distance_matrix, k=1)
        self.pheromone_matrix = np.triu(initial_pheromone * np.ones_like(self.distance_matrix), k=1)
        # 路径级别矩阵
        self.route_level_matrix = np.triu(np.ones_like(self.distance_matrix) * initial_route_level, k=1)
        # 每一代的最优距离列表
        self.optimal_distance_of_every_iteration = []
        # 每一代的当前最优距离列表
        self.current_optimal_distance_of_every_iteration = []
    
    def calc_move_prob_matrix(self, passed_city, not_passed_city):
        """
            passed_city:每只蚂蚁已经经过的城市
            not_passed_city:每只蚂蚁未经过的城市
            返回未经过城市中每个城市被选择的概率矩阵move_prob_matrix,形状为[self.ant_count, np.array(not_passed_city).shape[1]]
        """
        move_prob_matrix = []
        for i in range(self.ant_count):
            # 由于都是上三角矩阵,因此,如果路径为i到j,且i > j的,需要对掉,变为j到i
            start = np.array([passed_city[i][-1]] * len(not_passed_city[i]))
            end = np.array(not_passed_city[i])
            bool_index = start > end
            start[bool_index] = end[bool_index]
            end[bool_index] = passed_city[i][-1]
            # 找出每条未经过路径上的信息素not_passed_route_pheromone以及启发信息not_passed_route_heuristic_information,
            # 其长度均为未经过城市的个数
            not_passed_route_pheromone = self.pheromone_matrix[start, end]
            not_passed_route_heuristic_information = self.heuristic_information_matrix[start, end]
            move_prob_matrix.append(not_passed_route_pheromone * not_passed_route_heuristic_information ** self.beta / np.sum(not_passed_route_pheromone * not_passed_route_heuristic_information ** self.beta))
        return np.array(move_prob_matrix)
    
    def calc_route_distance(self, route):
        """
            route:表示一次循环的路径,例如[0, 2, 1, 4, 3],表示0->2->1->4->3->0
            返回这条路径的长度
        """
        distance = 0
        for i in range(len(route) - 1):
            min_value, max_value = sorted([route[i], route[i + 1]])
            distance += self.distance_matrix[min_value, max_value]
        min_value, max_value = sorted([route[0], route[1]])
        distance += self.distance_matrix[min_value, max_value]
        return distance
    
    def g_function(self):
        """
            更新信息素矩阵
        """
        self.pheromone_matrix = np.sqrt((self.max_pheromone ** 2 - 1) / (self.M - 1) * (self.route_level_matrix - 1) + 1)
        
    def run(self):
        """
            迭代寻优,返回最优路径以及最优路径长度
        """
        # 随即初始化一个当前最优解, current_optimal_route表示当前最优路径,current_optimal_distance表示当前最优路径的长度
        current_optimal_route = rd.permutation(np.arange(self.N))
        current_optimal_distance = self.calc_route_distance(current_optimal_route)
        self.current_optimal_distance_of_every_iteration.append(current_optimal_distance)
        # 控制循环代数
        for times in range(1, 1 + self.run_times):
            if times % int(0.1 * self.run_times) == 0:
                print("第%d次迭代:" % times)
                print("最优路径:", current_optimal_route)
                print("最优路径长度:", current_optimal_distance)
            # 每只蚂蚁已经经过的城市列表[lst1, lst2, lst3, ...],lst1表示第一只蚂蚁经过城市列表,lst1[-1]表示蚂蚁1当前所在城市,以此类推
            passed_city = [[rd.randint(0, self.N)] for i in range(self.ant_count)]
            # 每只蚂蚁未经过的城市列表[lst1, lst2, ...],lst1表示第一只蚂蚁未经过的城市列表,以此类推
            not_passed_city = [list(set(range(self.N)) - set(i)) for i in passed_city]
            # 判断每只蚂蚁是否均遍历完所有城市,如果遍历完则跳出循环
            while len(np.unique(not_passed_city)) != 0:
                # 每次循环所有蚂蚁选择一个城市进行状态转移
                # 计算未经过城市中每个城市被选择的概率矩阵move_prob_matrix,形状为[self.ant_count, np.array(not_passed_city).shape[1]]
                move_prob_matrix = self.calc_move_prob_matrix(passed_city, not_passed_city)
                # 求取被选择概率最大的城市索引
                select_city_index = np.argmax(move_prob_matrix, axis=1)
                # 进行状态转移,更新已经经过的城市列表以及未经过的城市列表
                for i in range(self.ant_count):
                    passed_city[i].append(not_passed_city[i].pop(select_city_index[i]))
            # 更新路径等级,首先进行惩罚
            self.route_level_matrix -= self.r_1
            self.route_level_matrix[self.route_level_matrix < 1] = 1
            # 更新当前最优路径以及当前最优路径长度
            # 计算所有蚂蚁经过的路径的路径长度
            distance_lst = [self.calc_route_distance(r) for r in passed_city]
            # 最优蚂蚁索引
            optimal_index = np.argmin(distance_lst)
            current_iter_optimal_route = passed_city[optimal_index]
            current_iter_optimal_distance = distance_lst[optimal_index]
            self.optimal_distance_of_every_iteration.append(current_iter_optimal_distance)
            if current_iter_optimal_distance < current_optimal_distance:
                current_optimal_distance = current_iter_optimal_distance
                current_optimal_route = current_iter_optimal_route
            self.current_optimal_distance_of_every_iteration.append(current_optimal_distance)
            # 更新路径等级,进行奖励
            for i in range(len(current_optimal_route) - 1):
                min_value, max_value = sorted([current_optimal_route[i], current_optimal_route[i + 1]])
                self.route_level_matrix[min_value, max_value] += self.r_2
            min_value, max_value = sorted([current_optimal_route[0], current_optimal_route[-1]])
            self.route_level_matrix[min_value, max_value] += self.r_2
            self.route_level_matrix[self.route_level_matrix > self.M] = self.M
            # 更新信息素
            self.g_function()
#             print("最优路径:", current_optimal_route)
#             print("最优路径长度:", current_optimal_distance)
        return current_optimal_route, current_optimal_distance


# In[6]:


fgp_aco = FGP_ACO(100, 3, 1, 50, 5, 50, 2000, data, 25, 100)
print("城市坐标:\n", fgp_aco.city_position_matrix)
print("城市间距离矩阵:\n", fgp_aco.distance_matrix)
print("信息素矩阵:\n", fgp_aco.pheromone_matrix)
print("启发信息矩阵:\n", fgp_aco.heuristic_information_matrix)
fgp_aco.run()


# In[16]:


ax = plt.subplot(1, 1, 1)
ax.scatter(np.arange(len(fgp_aco.optimal_distance_of_every_iteration)), fgp_aco.optimal_distance_of_every_iteration, alpha=0.3)
plt.show()

 

    原文作者:蚁群算法
    原文地址: https://blog.csdn.net/yy2050645/article/details/86471354
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞