蚁群算法 | 运筹优化

1、原理

蚁群算法是由自然界中蚂蚁觅食的行为而启发的。在自然界中,蚂蚁觅食过程中,蚁群总能够寻找到一条从蚁巢到食物源的最优路径。信息素是蚂蚁之间交流的工具之一,当有蚂蚁走过时,它将会在它行进的路上释放出信息素,并且这种信息素会议一定的速率散发掉。
一开始路上没有前面蚂蚁留下的信息素,蚂蚁朝着两个方向行进的概率是相等的;当有蚂蚁走过,它后面的蚂蚁通过路上信息素的浓度,做出决策,往左还是往右;
很明显,沿着短边的的路径上信息素将会越来越浓,从而吸引了越来越多的蚂蚁沿着这条路径行驶;
蚁群算法 | 运筹优化_第1张图片

2、算法流程

基本流程如下:
1、初始化信息素和蚂蚁位置。初始化蚂蚁数量、可行路段、每条路段距离、每条路段的初始信息素大小等信息;设定蚂蚁的起点、终点;
2. 计算每只蚂蚁的选择概率。每只蚂蚁在选择路径时,会考虑当前信息素浓度和距离等因素,计算出每条路径的选择概率。蚂蚁从起点出发根据信息素浓度,有一定的概率性选择路段,浓度越高,概率越大,逐步回到终点;
3. 计算每只蚂蚁的路径和适应度。根据选择概率,每只蚂蚁会沿着选择的路径前进,并计算出其路径长度或适应度值。
4. 更新信息素。蚂蚁在路径上释放信息素,并根据路径长度更新信息素浓度。信息素还会因为挥发效应而逐渐降低。
5.判断是否达到终止条件。可以设置迭代次数或判断蚂蚁的最优路径是否发生变化等终止条件。
6.输出最优解。当达到终止条件后,输出最优解即可。

3、优缺点

优点:

  1. 能够在多维度的搜索空间中进行搜索,并能够找到比较优的解;
  2. 没有要求搜索空间连续,可以在非连续的区域进行搜索;
  3. 对于多目标优化问题,可以比较好地处理;
  4. 能够通过增加信息素挥发速度和更新信息素浓度等措施来避免局部最优解。

缺点:

  1. 依赖于信息素的初值设定,选择不合适的初值可能会得到不太好的结果;
  2. 对于大型问题,需要寻找合适的参数并花费较多的计算资源;
  3. 算法结果可能受到启发式策略的影响,因此需要合适的策略设计。

4、TSP问题python实现

# 以下是一个简单的蚁群算法python实现示例,用于解决TSP问题:
#
# ```python
import numpy as np

# 参数设置
"""
这些参数是蚁群算法中的关键参数,具体含义如下:

-alpha: 信息素重要程度。用于蚂蚁在选择下一个节点时的信息素浓度的影响权重,alpha越大,蚂蚁更倾向于选择信息素浓度越高的路径。
alpha的取值越大,蚂蚁更加倾向于选择信息素浓度较高的路径,反之则更加依赖启发信息的作用。
- beta: 启发因子重要程度。用于蚂蚁在选择下一个节点时的启发信息的影响权重,beta越大,蚂蚁更倾向于选择启发信息更好的路径。
启发信息是指在蚁群算法中,通过对当前节点与目标节点的距离或者预估值的计算,为每个节点分配一个启发值。启发值代表了当前节点到目标节点的有益信息,能够帮助蚂蚁在路径选择时更好地指导方向。
启发信息的计算方式取决于所解决问题的具体特点。例如,解决旅行商问题时,启发值可以是当前节点与目标节点之间的直线距离,也可以是两点之间的曼哈顿距离。
如果是解决图的最短路径问题,启发值可以是当前节点到目标节点的预估最短距离值(例如使用A*算法)。
在蚁群算法中,启发信息可以有效地帮助蚂蚁在搜索过程中避免深度优先的搜索,从而更快地从历史的经验中学习,并选择一条最佳路径。
- rho: 信息素挥发因子。用于控制信息素浓度的挥发速度,rho越大,信息素挥发速度越快。
- Q: 信息素增量常数。用于控制信息素的更新量大小。
- ant_count: 蚂蚁数量。用于控制每次迭代中蚂蚁的数量,在实际应用中,通常选择适当的蚂蚁数量可以取得更好的效果。
- generation: 迭代次数。用于控制算法的收敛速度,迭代次数越多,算法越容易达到全局最优解,但时间复杂度也会相应增加。
"""
alpha = 1      # 信息素重要程度
beta = 5       # 启发因子重要程度
rho = 0.5      # 信息素挥发因子
Q = 100        # 信息素增量常数
ant_count = 10 # 蚂蚁数量
generation = 100 # 迭代次数

# 初始化城市坐标
distance_graph = np.array([[0, 20, 42, 35],
                           [20, 0, 30, 34],
                           [42, 30, 0, 12],
                           [35, 34, 12, 0]])

# 初始化信息素和启发因子
pheromone = np.ones(distance_graph.shape) / distance_graph
eta = 1 / (distance_graph + np.diag([1e10] * 4))

# 定义函数计算概率
"""
这是一个计算概率的函数,用于蚂蚁算法中选择下一个城市的概率计算。该函数的输入有两个参数:
-current_city`: 当前所在的城市
-allowed_cities`: 在当前情况下可以选择的城市列表
函数将根据指定的 `alpha` 和 `beta` 参数对蚂蚁在选择下一个城市时的信息素浓度和启发式信息进行权衡,计算出每个城市被选择的概率。
具体而言,首先将信息素浓度和启发式信息均使用指定的参数进行幂运算;然后将它们相乘得到所谓的“概率权值”,最后将所有城市的概率权值进行归一化。
函数返回的结果是一个代表每个城市被选择的概率的向量。
"""
def calculate_prob(current_city, allowed_cities):
    pheromone_powered = np.power(pheromone[current_city, allowed_cities], alpha)
    eta_powered = np.power(eta[current_city, allowed_cities], beta)
    probs = pheromone_powered * eta_powered
    probs = probs / np.sum(probs)
    return probs

# 定义函数选择下一个城市
def choose_next_city(current_city, allowed_cities):
    probs = calculate_prob(current_city, allowed_cities)
    next_city = np.random.choice(allowed_cities, p=probs)
    return next_city

# 定义函数计算路径长度
def calculate_distance(path):
    distance = 0
    for c in range(len(path) - 1):
        distance += distance_graph[path[c], path[c+1]]
    return distance

# 迭代搜索
"""
当蚂蚁经过一个城市时,它会释放信息素,如果多只蚂蚁经过同一个城市,那么这个城市上的信息素残留量就会增加,从而影响下一只蚂蚁选择该城市的概率。、
在算法的迭代过程中,信息素会逐渐挥发和更新,从而保持信息素分布的动态平衡。
"""
best_path = []
best_distance = np.inf
for g in range(generation):
    ant_paths = np.zeros((ant_count, distance_graph.shape[0]), dtype=int)

    for k in range(ant_count):
        ant_pos = np.random.randint(0, distance_graph.shape[0])
        ant_paths[k, 0] = ant_pos
        allowed_cities = list(range(distance_graph.shape[0]))
        allowed_cities.remove(ant_pos)

        for i in range(1, distance_graph.shape[0]):
            next_pos = choose_next_city(ant_pos, allowed_cities)
            ant_paths[k, i] = next_pos
            allowed_cities.remove(next_pos)
            ant_pos = next_pos

        distance = calculate_distance(ant_paths[k])
        pheromone_increment = np.zeros(distance_graph.shape)
        for c in range(distance_graph.shape[0] - 1):
            i, j = ant_paths[k, c], ant_paths[k, c+1]
            pheromone_increment[i][j] = 1 / distance

        pheromone = (1 - rho) * pheromone + rho * pheromone_increment

        if distance < best_distance:
            best_path = ant_paths[k]
            best_distance = distance

    print('Generation: {:2d} Shortest Distance: {:.2f}'.format(g, best_distance))

print('Best Path: {}'.format(best_path))
print('Best Distance: {:.2f}'.format(best_distance))
# ```
#
# 在上述示例中,我们使用numpy库处理矩阵数据,并设置了一些常用的蚁群算法参数,包括信息素重要程度、启发因子重要程度、信息素挥发因子、信息素增量常数、蚂蚁数量、迭代次数等。然后初始化城市坐标,并根据距离计算出启发因子。
#
# 接着,我们定义了两个函数:`calculate_prob`用于计算各城市的选择概率,`choose_next_city`用于选择下一个城市。在迭代搜索的过程中,我们首先随机选择一个起始城市,并根据选择概率逐步选择下一个城市,直到搜索完成。在每个迭代过程中,我们根据蚂蚁的选择路径更新信息素,并记录下最优路径和最短距离。最后输出结果。

你可能感兴趣的:(算法)