【人工智能】蚁群算法(密恐勿入)(三)

简介: 假设有一位邮递员,他从初始城市(任意一城市)出发,途径所有城市并回到初始城市,利用蚁群算法求得最短路径

4. TSP问题—蚁群算法实现(python版本)

问题背景:

假设有一位邮递员,他从初始城市(任意一城市)出发,途径所有城市并回到初始城市,利用蚁群算法求得最短路径

数据:

以下是10个城市的坐标数据:




城市
X坐标
Y坐标




A
5
10


B
6
15


C
10
15


D
14
14


E
20
10


F
16
5


G
8
5


H
4
8


I
8
12


J
12
12


准备阶段

  1. 首先,将数据存储在Graph中,并且计算各个城市之间的距离distances。
    ```python
    class Graph(object):
    def init(self, city_location, pheromone=1.0, alpha=1.0, beta=1.0):

     self.city_location = city_location
     self.n = len(city_location)
     # phernmone矩阵
     self.pheromone = [[pheromone for _ in range(self.n)] for _ in range(self.n)]
     self.alpha = alpha
     self.beta = beta
     # 城市之间的距离矩阵
     self.distances = self._generate_distances()
    

    欧式距离作为图的权重

    def _generate_distances(self):

     distances = []
     # 遍历行
     #   遍历列
     #       如果行值=列,比如(1,1)(2,2),这样就是相同的城市,则距离为零
     #       如果行值<列,比如(1,2)(2,3),这样就是不同的城市,距离按欧拉距离公式来算
     #       否则,将矩阵的斜对称位置上的距离来补(原因:城市之间距离矩阵是一个distances[i][j] = distances[j][i]特点的矩阵,这样的目的就是减少至少一半的计算)
     for index_i, _i in enumerate(self.city_location):
         row = []
         for index_j, _j in enumerate(self.city_location):
             if _i == _j:
                 row.append(0)
             elif _i < _j:
                 x1, y1 = self.city_location[str(_i)]
                 x2, y2 = self.city_location[str(_j)]
                 row.append(np.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2))
             else:
                 row.append(distances[index_j][index_i])
         distances.append(row)
     return distances
    
- 属性
    - `city_location`: 城市位置的字典
    - `n`: 城市的数量
    - `pheromone`: 蚂蚁留下的信息素的矩阵
    - `alpha`: 信息素强度的影响因子
    - `beta`: 启发式因子的影响因子
    - `distances`: 城市之间距离的矩阵
- 方法
    - `__init__(self, city_location, pheromone=1.0, alpha=1.0, beta=1.0)`: 对象初始化,计算出城市之间的距离矩阵
    - `_generate_distances(self)`: 计算城市之间的距离矩阵


 2. 那么,我们将各项能力赋予蚂蚁

    ```python
    class Ant(object):
        def __init__(self, graph, start_city):
            self.graph = graph
            self.start_city = start_city
            self.curr_city = start_city
            self.visited = [False for _ in range(graph.n)]
            self.visited[start_city] = True
            self.tour_length = 0
            self.tour = [start_city]

        def choose_next_city(self):
            # calculate probabilities of all cities
            probs = []
            total_prob = 0
            for i in range(self.graph.n):
                if not self.visited[i]:
                    prob = self.graph.pheromone[self.curr_city][i] ** self.graph.alpha * \\
                           (1.0 / self.graph.distances[self.curr_city][i]) ** self.graph.beta
                    probs.append((i, prob))
                    total_prob += prob
            # select the next city randomly based on the probabilities
            r = random.uniform(0, total_prob)
            upto = 0
            for i, prob in probs:
                if upto + prob >= r:
                    self.curr_city = i
                    self.visited[i] = True
                    self.tour.append(i)
                    self.tour_length += self.graph.distances[self.tour[-2]][i]
                    return
                upto += prob

        def tour_complete(self):
            return len(self.tour) == self.graph.n
- 属性:
    - `graph`: 图对象,表示要在其上运行蚁群算法的图
    - `start_city`: 整数,表示蚂蚁的起始城市
    - `curr_city`: 整数,表示蚂蚁当前所在城市
    - `visited`: 布尔列表,表示城市是否已被访问
    - `tour_length`: 浮点数,表示蚂蚁的路径长度
    - `tour`: 整数列表,表示蚂蚁的路径
- 方法:
    - `choose_next_city()`: 计算所有城市的概率,根据概率随机选择下一个城市
    - `tour_complete()`: 检查蚂蚁是否已经遍历完所有城市

算法构造

通过上面的准备,我们现阶段有了蚂蚁和城市图,那么,我们来规划一下算法的流程。把:

  1. 初始化蚂蚁和信息素矩阵。
  2. 蚂蚁根据信息素浓度和启发函数选择下一个节点。
  3. 蚂蚁在路径上释放信息素。
  4. 重复步骤2和3,直到所有蚂蚁都找到了解。
  5. 评估每条路径的适应度,并更新信息素矩阵。
  6. 重复步骤2到5,直到达到预设的迭代次数或者找到最优解。

这里要考虑选择哪一种更新策略、更新时机:

  • 静态规则(这里我选的这个)
  • 在每个迭代周期结束后进行更新,即在所有蚂蚁完成当前迭代周期后,根据其路径长度和信息素更新信息素浓度。
def ant_colony(graph, num_ants, num_iterations, evaporation_rate=0.5, q=500):
    shortest_tour = None  # 最短路径
    shortest_tour_length = float('inf')  # 最短路径长度
    for i in range(num_iterations):
        ants = [Ant(graph, random.randint(0, graph.n - 1)) for _ in range(num_ants)]  # 随机生成蚂蚁
        for ant in ants:
            while not ant.tour_complete():
                ant.choose_next_city()  # 选择下一个城市
            ant.tour_length += graph.distances[ant.tour[-1]][ant.start_city]  # 计算路径长度
            if ant.tour_length < shortest_tour_length:
                shortest_tour_length = ant.tour_length
                shortest_tour = ant.tour[:]
        for i in range(graph.n):
            for j in range(graph.n):
                if i != j:
                    graph.pheromone[i][j] *= (1 - evaporation_rate)  # 更新挥发信息素
                for ant in ants:
                    if (i, j) in zip(ant.tour, ant.tour[1:]):
                        graph.pheromone[i][j] += q / ant.tour_length  # 更新释放信息素
        return shortest_tour, shortest_tour_length
  • 注释:
    • shortest_tour:最短路径,初始化为 None。
    • shortest_tour_length:最短路径长度,初始化为正无穷。
    • ants:蚂蚁集合,随机生成。
    • ant:蚂蚁,从 graph 中随机选择一个起始城市开始走。
    • choose_next_city:选择下一个城市。
    • tour_length:路径长度,初始化为 0。
    • pheromone:信息素。
    • evaporation_rate:信息素挥发率。
    • q:信息素强度。
    • zip(ant.tour, ant.tour[1:]):将 ant.tour 中的相邻两个元素组成一个二元组 (i, j),便于后续计算。
    • 更新信息素时,需要更新挥发信息素和释放信息素。挥发信息素是指信息素随时间的推移而逐渐消失;释放信息素是指蚂蚁在路径上释放信息素,增强这条路径的吸引力。
    • 返回最短路径和最短路径长度。

      测试:

将数据和流程带入:

city_location = {
   
   
    'A': (5, 10),
    'B': (6, 15),
    'C': (10, 15),
    'D': (14, 14),
    'E': (20, 10),
    'F': (16, 5),
    'G': (8, 5),
    'H': (4, 8),
    'I': (8, 12),
    'J': (12, 12)
}

# 创建Graph对象
g = Graph(city_location)
shortest_tour, shortest_tour_length = ant_colony(graph=g, num_ants=500, num_iterations=1000)
print(shortest_tour,shortest_tour_length)

# 城市索引
city_index = {
   
   city: i for i, city in enumerate(sorted(city_location))}
# 城市索引
city_index = {
   
   city: i for i, city in enumerate(sorted(city_location))}
# 城市名称列表
shortest_tour = [list(city_index.keys())[i] for i in shortest_tour]
# 打印结果
print(shortest_tour)
g.plot_path(shortest_tour)

image.png
image.png

参考代码:

import math
import random

class Graph(object):
    def __init__(self, n, pheromone=1.0, alpha=1.0, beta=1.0):
        self.n = n
        self.pheromone = [[pheromone for _ in range(n)] for _ in range(n)]
        self.alpha = alpha
        self.beta = beta
        self.distances = self._generate_distances()

    def _generate_distances(self):
        # randomly generate distances between cities
        distances = []
        for i in range(self.n):
            row = []
            for j in range(self.n):
                if i == j:
                    row.append(0)
                elif j > i:
                    row.append(random.uniform(1, 10))
                else:
                    row.append(distances[j][i])
            distances.append(row)
        return distances

class Ant(object):
    def __init__(self, graph, start_city):
        self.graph = graph
        self.start_city = start_city
        self.curr_city = start_city
        self.visited = [False for _ in range(graph.n)]
        self.visited[start_city] = True
        self.tour_length = 0
        self.tour = [start_city]

    def choose_next_city(self):
        # calculate probabilities of all cities
        probs = []
        total_prob = 0
        for i in range(self.graph.n):
            if not self.visited[i]:
                prob = self.graph.pheromone[self.curr_city][i] ** self.graph.alpha * \\
                       (1.0 / self.graph.distances[self.curr_city][i]) ** self.graph.beta
                probs.append((i, prob))
                total_prob += prob
        # select the next city randomly based on the probabilities
        r = random.uniform(0, total_prob)
        upto = 0
        for i, prob in probs:
            if upto + prob >= r:
                self.curr_city = i
                self.visited[i] = True
                self.tour.append(i)
                self.tour_length += self.graph.distances[self.tour[-2]][i]
                return
            upto += prob

    def tour_complete(self):
        return len(self.tour) == self.graph.n

def ant_colony(graph, num_ants, num_iterations, evaporation_rate=0.5, q=500):
    shortest_tour = None
    shortest_tour_length = float('inf')
    for i in range(num_iterations):
        # initialize ants
        ants = [Ant(graph, random.randint(0, graph.n-1)) for _ in range(num_ants)]
        # have each ant choose a path
        for ant in ants:
            while not ant.tour_complete():
                ant.choose_next_city()
            ant.tour_length += graph.distances[ant.tour[-1]][ant.start_city]
            # check if this ant found a shorter tour
            if ant.tour_length < shortest_tour_length:
                shortest_tour_length = ant.tour_length
                shortest_tour = ant.tour[:]
        # update pheromones
        for i in range(graph.n):
            for j in range(graph.n):
                if i != j:
                    graph.pheromone[i][j] *= (1 - evaporation_rate)
                    for ant in ants:
                        if (i, j) in zip(ant.tour, ant.tour[1:]):
                            graph.pheromone[i][j] += q / ant.tour_length
    return shortest_tour, shortest_tour_length

# generate a 11-city TSP problem and solve it using the ant colony algorithm
graph = Graph(11)
shortest_tour, shortest_tour_length = ant_colony(graph, num_ants=10, num_iterations=50)

# print the shortest tour and its length
print("Shortest tour:", shortest_tour)
print("Shortest tour length:", shortest_tour_length)
写在最后,第二次上热门,流量还可以,我也是认真对待了这篇文章,写这篇博客的原因就是顺便把老师的作业也写了,作业你们也看到了,就是用代码实现蚁群算法去解决TSP问题,对于蚁群算法,我也是第一次去学习,并不是你们所认识的“佬”,说是博客,其实更像一篇记录我学习过程的日记,对于人工智能,说实话,挺有意思的,但考虑到本身实力情况,只能当作暂时的兴趣,大概这门课结课的时候,人工智能系列估计就不更了,唉毕竟是兴趣,不能吃饭,我的实力也不可能达到那些“佬”级别,下一篇估计也快了,应该是神经网络(泛泛而谈),有像了解的可以期待一下,我尽量把正确的,易懂的,可能老师考虑不到的方面给你们讲清楚,现学现卖的优势就是能将难点给它点出来。
相关文章
|
21天前
|
机器学习/深度学习 算法 TensorFlow
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
动物识别系统。本项目以Python作为主要编程语言,并基于TensorFlow搭建ResNet50卷积神经网络算法模型,通过收集4种常见的动物图像数据集(猫、狗、鸡、马)然后进行模型训练,得到一个识别精度较高的模型文件,然后保存为本地格式的H5格式文件。再基于Django开发Web网页端操作界面,实现用户上传一张动物图片,识别其名称。
53 1
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
|
21天前
|
机器学习/深度学习 人工智能 算法
植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面
植物病害识别系统。本系统使用Python作为主要编程语言,通过收集水稻常见的四种叶片病害图片('细菌性叶枯病', '稻瘟病', '褐斑病', '稻瘟条纹病毒病')作为后面模型训练用到的数据集。然后使用TensorFlow搭建卷积神经网络算法模型,并进行多轮迭代训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地模型文件。再使用Django搭建Web网页平台操作界面,实现用户上传一张测试图片识别其名称。
72 21
植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面
|
21天前
|
机器学习/深度学习 人工智能 算法
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
鸟类识别系统。本系统采用Python作为主要开发语言,通过使用加利福利亚大学开源的200种鸟类图像作为数据集。使用TensorFlow搭建ResNet50卷积神经网络算法模型,然后进行模型的迭代训练,得到一个识别精度较高的模型,然后在保存为本地的H5格式文件。在使用Django开发Web网页端操作界面,实现用户上传一张鸟类图像,识别其名称。
69 12
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
|
20天前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
46 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
|
16天前
|
机器学习/深度学习 人工智能 算法
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
文本分类识别系统。本系统使用Python作为主要开发语言,首先收集了10种中文文本数据集("体育类", "财经类", "房产类", "家居类", "教育类", "科技类", "时尚类", "时政类", "游戏类", "娱乐类"),然后基于TensorFlow搭建CNN卷积神经网络算法模型。通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型,并保存为本地的h5格式。然后使用Django开发Web网页端操作界面,实现用户上传一段文本识别其所属的类别。
31 1
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
【自然语言处理】TF-IDF算法在人工智能方面的应用,附带代码
TF-IDF算法在人工智能领域,特别是自然语言处理(NLP)和信息检索中,被广泛用于特征提取和文本表示。以下是一个使用Python的scikit-learn库实现TF-IDF算法的简单示例,并展示如何将其应用于文本数据。
216 65
|
16天前
|
机器学习/深度学习 人工智能 算法
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台。果蔬识别系统,本系统使用Python作为主要开发语言,通过收集了12种常见的水果和蔬菜('土豆', '圣女果', '大白菜', '大葱', '梨', '胡萝卜', '芒果', '苹果', '西红柿', '韭菜', '香蕉', '黄瓜'),然后基于TensorFlow库搭建CNN卷积神经网络算法模型,然后对数据集进行训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地文件方便后期调用。再使用Django框架搭建Web网页平台操作界面,实现用户上传一张果蔬图片识别其名称。
36 0
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
21天前
|
机器学习/深度学习 存储 人工智能
文本情感识别分析系统Python+SVM分类算法+机器学习人工智能+计算机毕业设计
使用Python作为开发语言,基于文本数据集(一个积极的xls文本格式和一个消极的xls文本格式文件),使用Word2vec对文本进行处理。通过支持向量机SVM算法训练情绪分类模型。实现对文本消极情感和文本积极情感的识别。并基于Django框架开发网页平台实现对用户的可视化操作和数据存储。
24 0
文本情感识别分析系统Python+SVM分类算法+机器学习人工智能+计算机毕业设计
|
20天前
|
算法
基于ACO蚁群优化的UAV最优巡检路线规划算法matlab仿真
该程序基于蚁群优化算法(ACO)为无人机(UAV)规划最优巡检路线,将无人机视作“蚂蚁”,巡检点作为“食物源”,目标是最小化总距离、能耗或时间。使用MATLAB 2022a版本实现,通过迭代更新信息素浓度来优化路径。算法包括初始化信息素矩阵、蚂蚁移动与信息素更新,并在满足终止条件前不断迭代,最终输出最短路径及其长度。
|
2月前
|
人工智能 自然语言处理 算法
【人工智能】TF-IDF算法概述
TF-IDF算法,全称Term Frequency-Inverse Document Frequency(词频-逆文档频率),是一种在信息检索和文本挖掘领域广泛应用的加权技术。它通过评估一个词语在文档中的重要程度,来挖掘文章中的关键词,进而用于文本分析、搜索引擎优化等场景。其核心思想是:如果某个词或短语在一篇文章中出现的频率高(TF高),且在其他文章中很少出现(IDF也高),则认为这个词或短语具有很好的类别区分能力,适合用来代表这篇文章的内容。 具体而言,TF-IDF由两部分组成,即词频(TF)和逆文档频率(IDF)。词频(TF)指的是某一个给定的词在该文件中出现的频率。这个数值通常会被归一化
31 3