蚁群算法解决TSP(旅行商)问题

2023-11-17


一、前言

蚁群算法(Ant Colony Optimization,ACO)是一种模拟自然界中蚂蚁觅食行为的优化算法。在蚁群算法中,蚂蚁寻找食物的方式被模拟为一种通过信息素通信来协作搜索解空间的算法。

蚁群算法要求考虑到多个蚂蚁之间相互交流信息的影响,因此也称作反向分布式系统中的元启发式,并已经成功用于旅行商问题(TSP)、车辆路径规划问题(VRP)等优化领域。它利用蚁群通过沿着积累了更多信息素的路径通信,集体行动实现优化目标的最大化或最小化,同时还具有鲁棒性、适应性强等优点。蚂蚁算法可以简单易用地处理复杂的组合优化问题,这些问题在传统优化算法中非常难以解决。

在这里插入图片描述

蚁群算法的基本原理:

蚂蚁在路径上释放信息素,如果遇到没有走过的路口,就随机选择一个路径行走。同时,释放与路径长度有关的信息素,信息素浓度与路径长度成反比。后来的蚂蚁再次碰到该路口时就选择信息素浓度较高的路径,由于走的蚂蚁多,故最优路径上的浓度越来越大,最终蚁群找到最优寻食路径。

其中的基本过程

1.初始化信息素和距离矩阵: 定义初始城市路径和信息素矩阵、计算城市之间的距离矩阵。

2.蚂蚁寻径: 每个蚂蚁依次从起点出发,根据已有信息素和启发式规则(例如较短路径和较小价值)选择下一个城市。

3.更新信息素: 根据每个蚂蚁走过路径的质量,在路径上留下新的信息素。

4.计算路径长度: 计算每条路径的长度。

5.更新最优路径: 更新存储已发现最优路径。

然后就不断的重复步骤2-5直到符合停止条件(例如达到预定迭代次数或者路径长度足够接近最佳路径),就会得到全局最优解或接近最优的解。

实现步骤需要考虑一些细节,例如实际中如何转化城市、如何更新信息素、如何建立随机概率模型等问题。 具体来说,每个蚂蚁需要记录它所访问的城市和所留下的路径信息素,以及通过某种随机方式在选择下一个城市时引入一定的探索性。若在已访问的城市集合中不存在未访问过的城市,蚂蚁就返回出发城市
最后,从所有完成迭代的蚂蚁中找到最小路径长度和对应的路径即可。当然,要建立合适的实验环境和调整参数,以保证算法的有效性和性能。

二、状态问题

假设有n个城市,则用一个长度为n的01串来表示一个可行的解(路径),其中每个0或1代表这条路径中对应位置的城市是否被访问过。例如,1101001表示这样的一条路径:第1、2、5、7个城市被访问过,而其它城市没有,这是一种经典的遗传算法(GA)的编码方式。

在蚁群算法中,可以直接使用与遗传算法类似的方式来进行状态的表示和操作,不过需要注意以下几点:

信息素矩阵的维度要对应城市的数量,以便蚂蚁在路径选择时可正常参考信息素矩阵。

在更新信息素时,需要特别关注路径端点处的信息素更新规则以及数据结构的选择,例如多次迭代时如何递减信息素强度?

在探索新路径时,需要避免在已经访问过的城市中再次搜索,同时还要避免陷入死循环和过早收敛等问题。

针对以上问题,可以结合具体的场景和应用需求进行实现和调试,以获得更优的效果。

1.城市被选择的概率由距离和信息素浓度共同决定

在这里插入图片描述
蚂蚁在选择要走的城市的时候,为了避免陷入局部最优解,故不能够只选择信息素浓度大和距离小的路径,在这里可以采用轮盘赌的方法进行选取。

   # 选择下一个城市
    def __choose_next_city(self):
        next_city = -1
        select_city_prob = [0.0 for each in range(city_num)]  # 存储选择每个城市的概率
        total_prob = 0.0

        # 获取去每个城市的概率
        for index in range(city_num):
            if self.open_table_city[index]:  # 如果index城市没有被探索过,就计算选择这个城市的概率;已经探索过的话不可以再重探索这个城市
                try:
                    # 计算概率,与信息浓度成正比,与距离成反比
                    select_city_prob[index] = pow(pheromone_graph[self.current_city][index], ALPHA) * pow((1.0 / distance_graph[self.current_city][index]), BETA)
                    total_prob += select_city_prob[index]
                except ZeroDivisionError as e:
                    print('Ant ID:{ID},current city:{current},target city{target}'.format(ID=self.ID,current=self.current_city,target=index))
                    sys.exit(1)

        # 采用轮盘赌方法选择下一个行走的城市
        if total_prob > 0.0:
            # 产生一个随机概率
            temp_prob = random.uniform(0.0, total_prob)
            for index in range(city_num):
                if self.open_table_city[index]:
                    # 轮次相减
                    temp_prob -= select_city_prob[index]
                    if temp_prob < 0.0:
                        next_city = index
                        break

        # 如果next_city=-1,则没有利用轮盘赌求出要去的城市
        # 通过随机生成的方法生成一个城市
        if next_city == -1:
            next_city = random.randint(0, city_num - 1)
            while ((self.open_table_city[next_city]) == False):  # 如果next_city已经被访问过,则需要重新生成
                next_city = random.randint(0, city_num - 1)

        return next_city

2.信息素更新

采用局部更新原则,即在所有蚂蚁完成一次转移之后执行信息素浓度的更新,其中 更新后的信息素浓度=没有挥发的信息素+新产生的信息素

在这里插入图片描述

# 更新信息素
    def __update_pheromone_graph(self):
        temp_pheromone = [[0.0 for i in range(city_num)] for j in range(city_num)]

        for ant in self.ants:
            for i in range(1, city_num):
                start, end = ant.path[i - 1], ant.path[i]
                # 留下的信息素浓度与蚂蚁所走路径总距离成反比
                temp_pheromone[start][end] += Q / ant.total_distance
                temp_pheromone[end][start] = temp_pheromone[start][end]
            #更新尾部到头部的信息浓度
            temp_pheromone[ant.path[city_num-1]][ant.path[0]] += Q/ant.total_distance
            temp_pheromone[ant.path[0]][ant.path[city_num-1]] = temp_pheromone[ant.path[city_num-1]][ant.path[0]]

        # 更新信息素,新的信息素等于信息素增量加上没有挥发掉的信息素
        for i in range(city_num):
            for j in range(city_num):
                pheromone_graph[i][j] = (1 - RHO) * pheromone_graph[i][j] + temp_pheromone[i][j]

三、整体实现

ALPHA:信息启发因子,信息浓度对于路径选择所占的比重

BETA: 期望启发式因子,BETA越大,蚁群就越容易选择局部较短路径,
这时算法的收敛速度加快;但是随机性却不高,容易得到局部的最优解.

BETA: 信息挥发因子,RHO过小,在各路径下残留的信息素过多,导致无效的路径
被持续搜索,影响到算法的收敛速率;RHO过大无效的路径虽然可以被排除搜索,
但是有效地路径也会被放弃搜索,影响到最后的最优值搜索.


import copy
import random
import threading
import tkinter
from functools import reduce
import sys

(ALPHA, BETA, RHO, Q) = (1.0, 2.0, 0.5, 100.0)
# 城市数目,蚁群数目
(city_num, ant_num) = (50, 50)

# 城市对应点的坐标
distance_x = [
    178, 272, 176, 171, 650, 499, 267, 703, 408, 437, 491, 74, 532, 416, 626,
    42, 271, 359, 163, 508, 229, 576, 147, 560, 35, 714, 757, 517, 64, 314,
    675, 690, 391, 628, 87, 240, 705, 699, 258, 428, 614, 36, 360, 482, 666,
    597, 209, 201, 492, 294]
distance_y = [
    170, 395, 198, 151, 242, 556, 57, 401, 305, 421, 267, 105, 525, 381, 244,
    330, 395, 169, 141, 380, 153, 442, 528, 329, 232, 48, 498, 265, 343, 120,
    165, 50, 433, 63, 491, 275, 348, 222, 288, 490, 213, 524, 244, 114, 104,
    552, 70, 425, 227, 331]

# 城市距离和信息素,采用二维数组的形式存储
# 初始化城市距离为0,信息素浓度为1
distance_graph = [[0.0 for col in range(city_num)] for raw in range(city_num)]
pheromone_graph = [[1.0 for col in range(city_num)] for raw in range(city_num)]


class Ant(object):
    # 初始化
    def __init__(self, ID):
        self.ID = ID
        self.__clean_data()  # 初始化出生点

    # 初始化数据
    def __clean_data(self):
        self.path = []  # 当前蚂蚁的行走路径
        self.total_distance = 0.0  # 当前蚂蚁行走的总长度
        self.move_count = 0  # 当前蚂蚁的行走次数
        self.current_city = -1  # 当前蚂蚁的所在城市
        self.open_table_city = [True for each in range(city_num)]  # 探索城市的状态,True表示未被探索果,False表示已经被探索过

        city_index = random.randint(0, city_num - 1)  # 随机初始生成点
        self.current_city = city_index
        self.path.append(city_index)
        self.open_table_city[city_index] = False
        self.move_count = 1

    # 选择下一个城市
    def __choose_next_city(self):
        next_city = -1
        select_city_prob = [0.0 for each in range(city_num)]  # 存储选择每个城市的概率
        total_prob = 0.0

        # 获取去每个城市的概率
        for index in range(city_num):
            if self.open_table_city[index]:  # 如果index城市没有被探索过,就计算选择这个城市的概率;已经探索过的话不可以再重探索这个城市
                try:
                    # 计算概率,与信息浓度成正比,与距离成反比
                    select_city_prob[index] = pow(pheromone_graph[self.current_city][index], ALPHA) * pow((1.0 / distance_graph[self.current_city][index]), BETA)
                    total_prob += select_city_prob[index]
                except ZeroDivisionError as e:
                    print('Ant ID:{ID},current city:{current},target city{target}'.format(ID=self.ID,current=self.current_city,target=index))
                    sys.exit(1)

        # 采用轮盘赌方法选择下一个行走的城市
        if total_prob > 0.0:
            # 产生一个随机概率
            temp_prob = random.uniform(0.0, total_prob)
            for index in range(city_num):
                if self.open_table_city[index]:
                    # 轮次相减
                    temp_prob -= select_city_prob[index]
                    if temp_prob < 0.0:
                        next_city = index
                        break

        # 如果next_city=-1,则没有利用轮盘赌求出要去的城市
        # 通过随机生成的方法生成一个城市
        if next_city == -1:
            next_city = random.randint(0, city_num - 1)
            while ((self.open_table_city[next_city]) == False):  # 如果next_city已经被访问过,则需要重新生成
                next_city = random.randint(0, city_num - 1)

        return next_city

    # 计算路径总距离
    def __cal_total_distance(self):
        temp_distance = 0.0

        for i in range(1, city_num):
            end = self.path[i]
            start = self.path[i - 1]
            temp_distance += distance_graph[start][end]

        # 回路
        start = city_num-1
        end = 0
        temp_distance += distance_graph[start][end]
        self.total_distance = temp_distance

    # 移动操作
    def __move(self, next_city):
        self.path.append(next_city)
        self.open_table_city[next_city] = False
        self.total_distance += distance_graph[self.current_city][next_city]
        self.current_city = next_city
        self.move_count += 1

    # 搜索路径
    def search_path(self):
        # 初始化数据
        self.__clean_data()

        # 搜索路径,遍历完所有的城市为止
        while self.move_count < city_num:
            next_city = self.__choose_next_city()
            # 移动
            self.__move(next_city)

        # 计算路径总长度
        self.__cal_total_distance()


class TSP(object):
    # 初始化
    def __init__(self, root, width=800, height=600, n=city_num):

        # 创建画布
        self.root = root
        self.width = width
        self.height = height

        # 城市数目初始化为city_num
        self.city_num = city_num

        self.canvas = tkinter.Canvas(root,
                                     width=self.width,
                                     height=self.height,
                                     bg='#EBEBEB',
                                     xscrollincrement=1,
                                     yscrollincrement=1)

        self.canvas.pack(expand=tkinter.YES, fill=tkinter.BOTH)
        self.title("TSP蚁群算法(n:初始化,e:开始搜索,s:停止搜索,q:退出程序)")
        self.__r = 5
        self.__lock = threading.RLock()  # 线程锁
        self.bindEvents()
        self.new()

        # 计算城市之间的距离
        for i in range(city_num):
            for j in range(city_num):
                temp_distance = pow(distance_x[i] - distance_x[j], 2) + pow(distance_y[i] - distance_y[j], 2)
                temp_distance = pow(temp_distance, 0.5)
                distance_graph[i][j] = float(int(temp_distance + 0.5))

        self.ants = [Ant(ID) for ID in range(ant_num)]  # 初始蚁群
        self.best = Ant(-1)  # 初始最优解
        self.best.total_distance = 1 << 31  # 初始最大距离
        self.iter = 1  # 初始化迭代次数

    # 更改标题
    def title(self, s):
        self.root.title(s)

    # 初始化
    def new(self, evt=None):

        # 停止线程
        self.__lock.acquire()
        self.__running = False
        self.__lock.release()

        self.clear()  # 清除信息
        self.nodes = []  # 节点坐标
        self.nodes2 = []  # 节点对象

        # 初始化城市节点
        for i in range(len(distance_x)):
            # 在画布上画出初始坐标
            x = distance_x[i]
            y = distance_y[i]
            self.nodes.append((x, y))
            # 生成节点椭圆,半径为self.__r
            node = self.canvas.create_oval(
                x - self.__r,
                y - self.__r,
                x + self.__r,
                y + self.__r,
                fill="#ff0000",  # 填充白色
                outline="#000000",  # 轮框白色
                tags="node")
            self.nodes2.append(node)

            # 显示坐标
            self.canvas.create_text(x,
                                    y - 10,
                                    text='(' + str(x) + ',' + str(y) + ')',
                                    fill='black')

        # 初始化城市之间的信息素
        for i in range(city_num):
            for j in range(city_num):
                pheromone_graph[i][j] = 1.0
        self.best = Ant(-1)  # 初始最优解
        self.best.total_distance = 1 << 31  # 初始最大距离
        self.iter = 1  # 初始化迭代次数

    # 将节点按照order顺序连线
    def line(self, order):
        # 删除原线
        self.canvas.delete("line")

        def line2(i1, i2):
            p1, p2 = self.nodes[i1], self.nodes[i2]
            self.canvas.create_line(p1, p2, fill="#000000", tags="line")
            return i2

        # order[-1]初始点
        reduce(line2, order, order[-1])


    # 清除画布
    def clear(self):
        for item in self.canvas.find_all():
            self.canvas.delete(item)

    # 退出程序
    def quit(self, evt=None):
        self.__lock.acquire()
        self.__running = False
        self.__lock.release()
        self.root.destroy()
        print("\n程序已经退出...")
        sys.exit()

    # 停止搜索
    def stop(self, evt=None):
        self.__lock.acquire()
        self.__running = False
        self.__lock.release()

    # 开始搜索
    def search_path(self, evt=None):
        # 开启线程
        self.__lock.acquire()
        self.__running = True
        self.__lock.release()

        while self.__running:
            # 遍历每一只蚂蚁
            for ant in self.ants:
                # 搜索每一条路径
                ant.search_path()
                # 判断是否是最优解
                if ant.total_distance < self.best.total_distance:
                    self.best =  copy.deepcopy(ant)
            # 更新信息素
            self.__update_pheromone_graph()
            print("迭代次数:", self.iter, "最佳路径总距离", int(self.best.total_distance))
            # 连线
            self.line(self.best.path)
            # 设置标题
            self.title("TSP蚁群算法(n:初始化,e:开始搜索,s:停止搜索,q:退出程序),迭代次数:%d,总距离%d" % (self.iter,int(self.best.total_distance)))
            # 更新画布
            self.canvas.update()
            self.iter += 1

        # 更新信息素

    def __update_pheromone_graph(self):
        temp_pheromone = [[0.0 for i in range(city_num)] for j in range(city_num)]

        for ant in self.ants:
            for i in range(1, city_num):
                start, end = ant.path[i - 1], ant.path[i]
                # 留下的信息素浓度与蚂蚁所走路径总距离成反比
                temp_pheromone[start][end] += Q / ant.total_distance
                temp_pheromone[end][start] = temp_pheromone[start][end]
            #更新尾部到头部的信息浓度
            temp_pheromone[ant.path[city_num-1]][ant.path[0]] += Q/ant.total_distance
            temp_pheromone[ant.path[0]][ant.path[city_num-1]] = temp_pheromone[ant.path[city_num-1]][ant.path[0]]

        # 更新信息素,新的信息素等于信息素增量加上没有挥发掉的信息素
        for i in range(city_num):
            for j in range(city_num):
                pheromone_graph[i][j] = (1 - RHO) * pheromone_graph[i][j] + temp_pheromone[i][j]

        # 按键响应

    def bindEvents(self):

        self.root.bind("q", self.quit)  # 退出程序
        self.root.bind("e", self.search_path)  # 开始搜索
        self.root.bind("s", self.stop)  # 停止搜索
        self.root.bind("n", self.new)  # 初始化

        # 主循环

    def mainloop(self):
        self.root.mainloop()


if __name__ == '__main__':
    TSP(tkinter.Tk()).mainloop()

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

蚁群算法解决TSP(旅行商)问题 的相关文章

  • 如何有条件地组合两个相同形状的 numpy 数组

    这听起来很简单 但我想我把它想得太复杂了 我想创建一个数组 其元素是从两个形状相同的源数组生成的 具体取决于源数组中哪个元素更大 为了显示 import numpy as np array1 np array 2 3 0 array2 np
  • 将 Django 表单中的所有 CharField 表单字段输入转换为小写

    我使用 Django 表单进行用户注册 用户可以在其中输入优惠券代码 我希望在优惠券代码字段中输入的所有字符都转换为小写 我尝试过在保存方法 自定义清理方法和自定义验证器中使用 lower 但这些方法没有运气 下面是我的代码 class S
  • 为 PyCharm 中的所有配置设置相同的环境变量

    我有一个与 Celery 和很多不同的工作人员一起的项目 如何避免每次将 PyCharm 中的环境变量复制粘贴到每个运行 调试配置 有什么方法可以在项目设置中设置它们吗 找到解决方案here https stackoverflow com
  • multiprocessing.freeze_support()

    为什么多处理模块需要调用特定的function http docs python org dev library multiprocessing html multiprocessing freeze support在被 冻结 以生成 Wi
  • 基于 True/False 值的 Python 优雅赋值

    我想根据三个布尔值中的值设置一个变量 最直接的方法是 if 语句后跟一系列 elif if a and b and c name first elif a and b and not c name second elif a and not
  • pandas 两个数据框交叉连接[重复]

    这个问题在这里已经有答案了 我找不到有关交叉联接的任何内容 包括合并 联接或其他一些内容 我需要使用 my function 作为 myfunc 处理两个数据帧 相当于 for itemA in df1 iterrows for itemB
  • 以编程方式将列名称添加到 numpy ndarray

    我正在尝试将列名称添加到 numpy ndarray 然后按名称选择列 但这不起作用 我无法判断问题是在添加名称时出现 还是在稍后尝试调用它们时出现 这是我的代码 data np genfromtxt csv file delimiter
  • 在 Windows 上将 Word2vec 与 Tensorflow 结合使用

    In 本教程文件 https github com tensorflow models blob master tutorials embedding word2vec py L45通过 Tensorflow 找到以下行 第 45 行 来加
  • 熊猫记忆

    我有冗长的计算 我重复了很多次 因此 我想使用记忆 诸如jug http packages python org Jug and joblib http packages python org joblib memory html 与Pan
  • 在 GAE/Python 中放置一次性代码和每次代码的最佳位置在哪里?

    我是 Google App Engine 和 Python 的新手 我无法理解有关在 Google App Engine 上运行的 Python 应用程序的一些基本问题 如果我想要执行代码 对于每个传入的请求 我应该将其放在哪里 我们正在捕
  • 如何在 Keras 中使用部分输入进行训练,其余部分用于损失函数

    我是 Keras 新手 正在尝试实现神经网络机器学习模型 输入张量看起来像 X1 X2 和输出 Y 注意 X1 和 X2 是相关的 在模型中 只有 X1 将用于训练 但 X1 和 X2 都将传递给损失函数 该损失函数是 X1 X2 y pr
  • Python time.sleep - 永不醒来

    我认为这将是那些简单的问题之一 但它让我感到困惑 停止媒体 我是对的 找到了解决方案 查看答案 我正在使用 Python 的单元测试框架来测试多线程应用程序 很好而且很直接 我有 5 个左右的工作线程监视一个公共队列 以及一个为它们制作工作
  • 如何将reportlab与Google应用程序引擎一起使用

    我无法在谷歌应用程序引擎下正确导入reportlab 根据以下guide http blog notdot net 2010 04 Generating PDFs on App Engine Python and introducing M
  • python 中的基本矩阵转置

    我尝试了 python 中矩阵转置的最基本方法 但是 我没有得到所需的结果 接下来是代码 A 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 print A def TS A B A for i in range len A
  • dask allocate() 或 apply() 中的变量列名

    我有适用于pandas 但我在将其转换为使用时遇到问题dask 有一个部分解决方案here https stackoverflow com questions 32363114 how do i change rows and column
  • python csv按列转换为字典

    是否可以将 csv 文件中的数据读取到字典中 使得列的第一行是键 同一列的其余行构成列表的值 例如 我有一个 csv 文件 strings numbers colors string1 1 blue string2 2 red string
  • DRF:以编程方式从 TextChoices 字段获取默认选择

    我们的网站是 Vue 前端 DRF 后端 在一个serializer validate 方法 我需要以编程方式确定哪个选项TextChoices类已被指定为模型字段的默认值 TextChoices 类 缩写示例 class PaymentM
  • 如何使用 FastAPI 在 HTMX 前端中使用 HX-Redirect?

    我试图在登录后在前端重定向 我像这样从我的 htmx 前端发出请求
  • 将数组从 .npy 文件读入 Fortran 90

    我使用 Python 以二维数组 例如 X 的形式生成一些初始数据 然后使用 Fortran 对它们进行一些计算 最初 当数组大小约为 10 000 x 10 000 时 np savetxt 在速度方面表现良好 但是一旦我开始增加数组的维
  • Python - 打印漂亮的 XML 为空标签文本创建开始和结束标签

    我正在编写一个 python 应用程序 它创建一个 ElementTree XML 然后使用 minidom 的 toprettyxml 将其写入文件 final tree minidom parseString ET tostring r

随机推荐

  • Appstore审核被拒-[4. DESIGN: PREAMBLE]

    Appstore审核被拒原文如下 原因是设置里有一个版本信息可以响应点击事件进入一个版本详情页 苹果要求版本更新必须使用iOS版本更新内置更新机制 4 DESIGN PREAMBLE Design Preamble The version
  • 【华为OD机试真题 python】二进制差异数【2022 Q4

    前言 华为OD笔试真题 python 本专栏包含华为OD机试真题 会实时更新收纳网友反馈 为大家更新最新的华为德科OD机试试题 为大家提供学习和练手的题库 订阅本专栏后可私信进交流群哦 题目仅供参考 千万不要照抄 题目描述 二进制差异数 对
  • CK草稿本

    调用流程 获得op ptr ck有个工厂模式 const auto op ptrs ck tensor operation device instance DeviceOperationInstanceFactory
  • leetcode无重复字符的最长字串 python实现

    无重复字符的最长字串是一道字符串处理算法的题目 在日常编程中 处理字符串是常见任务 用Python来实现leetcode这道算法题 该题目会涉及到一个概念 滑动窗口 一 题目描述 给定一个字符串 请你找出其中不含有重复字符的 最长子串 的长
  • mac系统vim无法退出insert模式(ESC无效)

    表现 Vim 进入 Insert 模式以后 按 ESC 无法退出 解决方案 按 ctrl c
  • 电感与磁珠

    电感最重要的公式 它说明了电感的很多特性 比如 电感电流不能突变 电感的储能大小 电感的电流与电压的相位关系 还有电感的阻抗为什么是jwL 电感电流不能突变 电感电流为什么不能突变呢 来看这个公式 U等于负的L乘以di比dt Di比dt是指
  • linux上开发应用程序_如何在Linux上安装软件应用程序

    linux上开发应用程序 如何在Linux上安装应用程序 与许多操作系统一样 该问题不仅有一个答案 应用程序可以来自许多来源 几乎无法计数 每个开发团队都可以以自己认为最佳的方式交付软件 知道如何安装给出的内容是成为操作系统的真正超级用户的
  • asn1编码格式的解析过程

    本文以x509的解析为例说明asn1的编码格式的解析逻辑 x509证书的解析实际上是asn1格式的解析 这里着重说的是asn1的ber编码的解析 总的来讲 asn1格式的解析过程有三个重要的元素 一个是asn1数据本身 一个是openssl
  • vue中引用cdn中的js文件或者json的用法

    1 现在有一个js文件要放在cdn上 这个js文件的内容如下 var testArr a 1 2 我要在vue项目中使用这个变量 因为这个变量可能是经常变化的 但是不能变化一次就打包一次 所以将他放在cdn上 有使用的话直接改变cdn上的j
  • vscode运行C语言踩坑记

    前言 本文对Vscode运行C语言代码报错进行整理 重点是头文件路径正确仍然报错找不到路径的解决办法 需要注意 VScode本身不具有编译运行代码能力 所以需要先安装对应的编译环境并下载插件 已安装编译器软件的可以参考如下连接进行配置 Vi
  • Kali之Web渗透-扫描工具-Burpsuite

    在学习Burpsuit之前 我先说一下什么是代理 就是代理网络用户去取得网络信息 作为一个在浏览器和目标应用程序之间的中间人 允许你拦截 查看 修改在两个方向上的原始数据流 形象地说 它是网络信息的中转站 一般情况下 我们使用浏览器直接去连
  • 无需破解,Python这个神器帮你免费获取资源,赶紧收藏!

    球鞋那么难抢 有没有抢限量版球鞋的神器 每当限量版球鞋开售的时候 几十万人一拥而入 能抽中的却是少数 朋友圈刷到别人中标的消息 心里又羡慕又有点酸 今年DUNK推出的时候 我表弟竟然中了两双 他跟女朋友一人一双 这运气太好了吧 他跟我炫耀的
  • 拯救者R7000P(R7 4800H + RTX 2060)安装ubuntu18.04时黑屏,无法进入安装界面

    问题描述 插入启动盘选择u盘启动后能进入GNU GRUB 选择Try ubunut或Install ubuntu后黑屏或报错 无法正常安装 常见于搭载nvidia系列显卡且无核显或集显的电脑 也发生在有核显但为AMD处理器的电脑上 原因分析
  • stata-描述性统计分析和回归指令

    文章目录 1 简单描述性统计分析 2 bootstrap统计量 有置信区间 前文中提到如何将xls格式的数据读入stata并且将其转换为dta格式的数据 向stata中加载数据并且转换为dta格式之后读取 1 简单描述性统计分析 在读入数据
  • python中if __name__ == '__main__': 的解析

    python中if name main 的解析 当你打开一个 py文件时 经常会在代码的最下面看到if name main 现在就来介 绍一下它的作用 模块是对象 并且所有的模块都有一个内置属性 name 一个模块的 name 的值取决于您
  • Spring-boot 结合Thymeleaf--拦截器--文件上传

    目录 Spring boot 结合Thymeleaf 官方文档 基本介绍 Thymeleaf 是什么 Thymeleaf 的优点 Thymeleaf 的缺点 Thymeleaf 机制说明 Thymeleaf 语法 表达式 1 表达式一览 2
  • 柏睿java实习一面面经分享

    说一下list下面的类都有哪些 ArrayList和LinkedList的特点 jvm堆内存模型 jvm的垃圾回收算法都有哪些 简单描述一下它们事务的特性你对sql的优化了解多少 它有哪些方法 数据库的锁都有哪些 分别叙述下它们说一下lin
  • 在共享dll中使用mfc_实战经验:在DLL中支持多语言

    在主程序中支持多语言 在主程序中建立不同的语言资源字符串 并调用API函数SetProcessPreferredUILanguages设置当前语言就可以实现多语言特性 在DLL中支持多语言 1 因为DLL是主程序加载阶段载入到进程地址空间的
  • node调用ffmpeg转流

    ffmpeg始终是音视频领域绕不过去的一个坎 也是一个特别好的工具 虽然再node库里面有根据ffmpeg编译的库 比如 libav js和fluent ffmpeg之类 但是调用原生的ffmpeg应用也是一种方法 这边先上代码再详解 H2
  • 蚁群算法解决TSP(旅行商)问题

    文章目录 一 前言 蚁群算法的基本原理 其中的基本过程 二 状态问题 1 城市被选择的概率由距离和信息素浓度共同决定 2 信息素更新 三 整体实现 一 前言 蚁群算法 Ant Colony Optimization ACO 是一种模拟自然界