基于模拟退火算法的TSP问题建模求解(Python)

基于模拟退火算法的TSP问题建模求解(Python)

  • 一、模拟退火算法(Simulated Annealing Algorithm,SAA)工程背景
    • 模拟退火算法用于优化问题求解原理
  • 二、旅行商问题(Travelling salesman problem,TSP)
    • TSP问题数学模型
  • 三、基于模拟退火算法的TSP问题建模求解
    • 3.1实例分析
      • 3.1.1导入库
      • 3.1.2数据
      • 3.1.3生成初始解
      • 3.1.4扰动生成新解
      • 3.1.5评价函数
      • 3.1.6Metropolis接受准则
      • 3.1.7模拟退火算法
    • 3.2完整代码
    • 3.3求解结果

一、模拟退火算法(Simulated Annealing Algorithm,SAA)工程背景

模拟退火算法(Simulated Annealing Algorithm)来源于固体退火原理,是一种基于概率的算法。将固体加温至充分高的温度,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,分子和原子越不稳定。而徐徐冷却时粒子渐趋有序,能量减少,原子越稳定。在冷却(降温)过程中,固体在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。模拟退火算法从某一较高初温出发,伴随温度参数的不断下降,结合概率突跳特性在解空间中随机寻找目标函数的全局最优解,即在局部最优解能概率性地跳出并最终趋于全局最优。模拟退火算法是通过赋予搜索过程一种时变且最终趋于零的概率突跳性,从而可有效避免陷入局部极小并最终趋于全局最优的串行结构的优化算法。

模拟退火算法用于优化问题求解原理

模拟退火算法包含两个部分即Metropolis算法和退火过程,分别对应内循环和外循环。外循环就是退火过程,将固体达到较高的温度(初始温度 T 0 T_0 T0),然后按照降温系数 α \alpha α使温度按照一定的比例下降,当达到终止温度 T f T_f Tf时,冷却结束,即退火过程结束;Metropolis算法是内循环,即在每次温度下,迭代L次,寻找在该温度下能量的最小值(即最优解)。下图中所示即为在一次温度下,跌代L次,固体能量发生的变化。

在该温度下,整个迭代过程中温度不发生变化,能量发生变化,当前一个状态x(n)的能量大于后一个状态x(n+1)的能量时,状态x(n)的解没有状态x(n+1)的解好,所以接受状态x(n+1),以 P = 1 P=1 P=1的概率接受。但是如果下一状态的能量比前一个状态的能量高时,则接受下一状态的概率为 P = e E ( n + 1 ) − E ( n ) T P=\text{e}^{\frac{E(n+1)-E(n)}{T}} P=eTE(n+1)E(n)

P = { 1 E ( n + 1 ) < E ( n ) e E ( n + 1 ) − E ( n ) T E ( n + 1 ) ≥ E ( n ) P=\begin{cases} 1 & E(n+1) < E(n) \\ \text{e}^{\frac{E(n+1)-E(n)}{T}} & E(n+1) \geq E(n) \\ \end{cases} P={1eTE(n+1)E(n)E(n+1)<E(n)E(n+1)E(n)

  • E(n):状态为x(n)时系统的能量,即TSP问题中目标函数值
  • T:当前温度,控制退火速率,即温度下降,最简单的下降方式是指数式下降:T(n) = α \alpha α T(n) ,n =1,2,3,…其中 α \alpha α是小于1的正数,一般取值为0.8到0.99之间。使的对每一温度,有足够的转移尝试,指数式下降的收敛速度比较慢。

用固体退火模拟组合优化问题,状态x(n)映射为问题的解,将内能E模拟为目标函数值f,温度T演化成控制迭代过程参数t,即得到解组合优化问题的模拟退火算法:由初始解i和控制参数初值t开始,对当前解重复“产生新解→计算目标函数差→接受或舍弃”的迭代,并逐步衰减t值,算法终止时的当前解即为所得近似最优解,退火过程由冷却进度表(Cooling Schedule)控制,包括控制参数的初值t及其衰减因子Δt、每个t值时的迭代次数L和停止条件Tf。而温度的作用就是来计算转移概率P的。当温度每次下降后,转移概率也发生变化,因此在所有温度下迭代L次的结果也都是不相同的。在每个温度下迭代L次来寻找当前温度下的最优解,然后降低温度继续寻找,直到到达终止温度,即转移概率P接近于0
在这里插入图片描述

对应于优化问题(min问题),如果当前解的目标函数值<新解的目标函数值,则无条件接受;如果当前解的目标函数值>=新解的目标函数值,以一定的概率接受新解作为当前解。

Metropolis算法就是如何在局部最优解的情况下让其跳出来(如图中B、C、E为局部最优),是退火的基础。1953年Metropolis提出重要性采样方法,即以概率来接受新状态,而不是使用完全确定的规则,称为Metropolis准则,计算量较低。

假设初始解为A,多次迭代之后更新到B的局部最优解,这时发现更新到解B时,目标函数值比A要低,则说明接近最优解了,因此百分百转移,到达解B后,发现下一步目标函数值上升了,如果是梯度下降则是不允许继续向前的,而这里会以一定的概率跳出这个坑,这各概率和当前的状态、能量等都有关系。在一开始需要T值较大,这样根据函数的单调性,可以看出接受差解的P是较大的,便于对全局进行搜索,而在后期温度下降,T值变小,当温度趋于零时,只能接受目标函数下降的,这有利于尽快收敛,完成迭代。

二、旅行商问题(Travelling salesman problem,TSP)

TSP问题数学模型

刘兴禄 -《运筹优化常用模型、算法及案例实战:Python+Java实现》总结了TSP问题共有3种数学模型:

  1. Dantzig-Fulkerson-Johnson model,DFJ模型(本文采用)
  2. Miller-Tucker-Zemlin model,MTZ模型
  3. 1-tree模型

DFJ模型,也是最常见的模型如下:

min ⁡ ∑ i ∈ V ∑ j ∈ V d i j x i j subject to ∑ j ∈ V x i j = 1 , ∀ i ∈ V , i ≠ j ∑ i ∈ V x i j = 1 , ∀ j ∈ V , i ≠ j ∑ i , j ∈ S x i j ≤ ∣ S ∣ − 1 , 2 ≤ ∣ S ∣ ≤ N − 1 , S ⊂ V x i j ∈ { 0 , 1 } , ∀ i , j ∈ V \begin{align} \min \quad & \sum_{i \in V}{}\sum_{j \in V} d_{ij}x_{ij}\\ \text{subject to} \quad &\sum_{j \in V} x_{ij} = 1, \quad \forall i \in V,i \neq j \\ &\sum_{i \in V}{x_{ij}} =1,\quad \forall j \in V ,i \neq j\\ & {\sum_{i,j \in S}{x_{ij}} \leq |S|-1,\quad 2\leq |S| \leq N-1, S \subset V}\\ &x_{ij} \in \{0,1\}, \quad \forall i,j \in V \end{align} minsubject toiVjVdijxijjVxij=1,iV,i=jiVxij=1,jV,i=ji,jSxijS1,2SN1,SVxij{0,1},i,jV

三、基于模拟退火算法的TSP问题建模求解

3.1实例分析

3.1.1导入库

import numpy as np 
import pandas as pd
import matplotlib.pyplot as plt

3.1.2数据

# 数据:城市以及坐标
city_coordinates = {
        0: (60, 200),
        1: (180, 200),
        2: (80, 180),
        3: (140, 180),
        4: (20, 160),
        5: (100, 160),
        6: (200, 160),
        7: (140, 140),
        8: (40, 120),
        9: (100, 120),
        10: (180, 100),
        11: (60, 80),
        12: (120, 80),
        13: (180, 60),
        14: (20, 40),
        15: (100, 40),
        16: (200, 40),
        17: (20, 20),
        18: (60, 20),
        19: (160, 20),
    }
num_city = len(city_coordinates)
f'城市数量: {num_city}'
'城市数量: 20'
# 距离矩阵
distance_matrix = np.empty(shape=(num_city, num_city), dtype=np.float_)
for i in range(num_city):
    xi, yi = city_coordinates[i]
    for j in range(num_city):
        xj, yj = city_coordinates[j]
        distance_matrix[i][j] = np.sqrt(np.power(xi - xj, 2) + np.power(yi - yj, 2))

3.1.3生成初始解

x = np.random.permutation(num_city)  # 初始解,编码采用常规的整数编码,如果城市数目为N,那么解就可以表达为1~N的随机排列,
x
array([ 4, 16, 17,  7,  5, 18, 15,  3,  0, 10,  8,  9, 14,  1, 12, 13,  6,
       11,  2, 19])

3.1.4扰动生成新解

def two_opt(x: np.ndarray):
    """
    2-opt swap,扰动生成新解
    :param x: 解
    :return: 新解
    """
    x = x.copy()
    r1 = np.random.randint(low=0, high=num_city)
    r2 = np.random.randint(low=0, high=num_city)
    x[r1], x[r2] = x[r2], x[r1]
    return x

x_ = two_opt(x)
x_
array([ 4, 16, 17,  9,  5, 18, 15,  3,  0, 10,  8,  7, 14,  1, 12, 13,  6,
       11,  2, 19])

3.1.5评价函数

def eval_func(x):
    """
    评价函数
    :param x: 解
    :return: 解的目标函数值
    """
    total_distance = 0
    for k in range(num_city - 1):
        total_distance += distance_matrix[x[k]][x[k + 1]]
    total_distance += distance_matrix[x[-1]][x[0]]
    return total_distance

objective_value_x = eval_func(x),  # x的目标函数值
objective_value_x_ = eval_func(x_) # x_的目标函数值
objective_value_x, objective_value_x_
((2666.7841429791642,), 2705.4679394931945)

3.1.6Metropolis接受准则

P = { 1 E ( n + 1 ) < E ( n ) e E ( n + 1 ) − E ( n ) T E ( n + 1 ) ≥ E ( n ) P=\begin{cases} 1 & E(n+1) < E(n) \\ \text{e}^{\frac{E(n+1)-E(n)}{T}} & E(n+1) \geq E(n) \\ \end{cases} P={1eTE(n+1)E(n)E(n+1)<E(n)E(n+1)E(n)

  • E(n):状态为x(n)时系统的能量,即TSP问题中目标函数值
  • T:当前温度,T控制退火速率,即温度下降,最简单的下降方式是指数式下降:T(n) = α \alpha α T(n) ,n =1,2,3,…其中 α \alpha α是小于1的正数,一般取值为0.8到0.99之间。使的对每一温度,有足够的转移尝试,指数式下降的收敛速度比较慢。
temp_current = 1e6
delta_temp = objective_value_x_ - objective_value_x
if delta_temp > 0:
    # 若新解目标函数值更差,则一定概率接受
    if np.random.uniform(0, 1) < 1. / np.exp(delta_temp / temp_current):
        x = x_
else:
    # TSP为极小化问题,若新解目标函数值更小,则无条件接受新解作为当前解
    x = x_
x
array([ 4, 16, 17,  9,  5, 18, 15,  3,  0, 10,  8,  7, 14,  1, 12, 13,  6,
       11,  2, 19])

3.1.7模拟退火算法

def run_simulated_annealing(temp_initial=1e6, temp_final=.1, alpha=.98):
    """
    :param temp_initial: 初始温度T0
    :param temp_final: 终止温度T0
    :param alpha:降温系数
    :return: 每一代最优解, 及解的目标函数值
    """
    temp_current = temp_initial  # 当前温度

    x = np.random.permutation(num_city)  # 初始解,编码采用常规的整数编码,如果城市数目为N,那么解就可以表达为1~N的随机排列,
    obj_value = eval_func(x)  # 初始解目标函数值

    global_best = x  # 全局最优解
    trace: List[Tuple[np.ndarray, float]] = [(x, obj_value)]  # 记录每一代最优解, 及解的目标函数值
    while temp_current > temp_final:  # 外循环:退火过程
        for i in range(1000):  # 内循环
            obj_value_old = eval_func(x)
            x_ = two_opt(x)
            obj_value_new = eval_func(x_)
            delta_temp = obj_value_new - obj_value_old
            if delta_temp > 0:
                if np.random.uniform(0, 1) < 1. / np.exp(delta_temp / temp_current):
                    x = x_
            else:
                x = x_
                global_best = x
        trace.append((global_best, eval_func(global_best)))
        temp_current *= alpha

    return trace

3.2完整代码

import logging
from typing import Dict, List, Tuple

import numpy as np
import matplotlib.pyplot as plt

logging.getLogger('matplotlib').setLevel(logging.WARNING)
# logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)


def read_dataset(data=1):
    city_coordinates_ = {
        0: (60, 200),
        1: (180, 200),
        2: (80, 180),
        3: (140, 180),
        4: (20, 160),
        5: (100, 160),
        6: (200, 160),
        7: (140, 140),
        8: (40, 120),
        9: (100, 120),
        10: (180, 100),
        11: (60, 80),
        12: (120, 80),
        13: (180, 60),
        14: (20, 40),
        15: (100, 40),
        16: (200, 40),
        17: (20, 20),
        18: (60, 20),
        19: (160, 20),
    }  # 数据1:城市以及坐标
    city_coordinates_att48 = {
        0: (6734, 1453),
        1: (2233, 10),
        2: (5530, 1424),
        3: (401, 841),
        4: (3082, 1644),
        5: (7608, 4458),
        6: (7573, 3716),
        7: (7265, 1268),
        8: (6898, 1885),
        9: (1112, 2049),
        10: (5468, 2606),
        11: (5989, 2873),
        12: (4706, 2674),
        13: (4612, 2035),
        14: (6347, 2683),
        15: (6107, 669),
        16: (7611, 5184),
        17: (7462, 3590),
        18: (7732, 4723),
        19: (5900, 3561),
        20: (4483, 3369),
        21: (6101, 1110),
        22: (5199, 2182),
        23: (1633, 2809),
        24: (4307, 2322),
        25: (675, 1006),
        26: (7555, 4819),
        27: (7541, 3981),
        28: (3177, 756),
        29: (7352, 4506),
        30: (7545, 2801),
        31: (3245, 3305),
        32: (6426, 3173),
        33: (4608, 1198),
        34: (23, 2216),
        35: (7248, 3779),
        36: (7762, 4595),
        37: (7392, 2244),
        38: (3484, 2829),
        39: (6271, 2135),
        40: (4985, 140),
        41: (1916, 1569),
        42: (7280, 4899),
        43: (7509, 3239),
        44: (10, 2676),
        45: (6807, 2993),
        46: (5185, 3258),
        47: (3023, 1942),
    }  # 数据2:att48.txt 城市以及坐标 答案有4种可能,不向上取整,除根号10是10601;不向上取整,不除根号10是33523;向上取整,除根号10是10628;向上取整,不除根号10是33609
    return city_coordinates_att48 if data == 1 else city_coordinates_


def get_distance_matrix(city_coordinates: Dict[int, Tuple[int, int]]) -> np.ndarray:
    distance_matrix = np.empty(shape=(num_city, num_city), dtype=np.float_)
    for i in range(num_city):
        xi, yi = city_coordinates[i]
        for j in range(num_city):
            xj, yj = city_coordinates[j]
            distance_matrix[i][j] = np.sqrt(np.power(xi - xj, 2) + np.power(yi - yj, 2))
    return distance_matrix


def eval_func(x):
    """
    评价函数
    :param x: 解
    :return: 解的目标函数值
    """
    total_distance = 0
    for k in range(num_city - 1):
        total_distance += distance_matrix[x[k]][x[k + 1]]
    total_distance += distance_matrix[x[-1]][x[0]]
    return total_distance


def two_opt(x: np.ndarray):
    """
    2-opt swap,扰动生成新解
    :param x: 解
    :return: 新解
    """
    x = x.copy()
    r1 = np.random.randint(low=0, high=num_city)
    r2 = np.random.randint(low=0, high=num_city)
    x[r1], x[r2] = x[r2], x[r1]
    return x


def run_simulated_annealing(temp_initial=1e6, temp_final=.1, alpha=.98) -> List:
    """
    :param temp_initial: 初始温度T0
    :param temp_final: 终止温度T0
    :param alpha:降温系数
    :return: 每一代最优解, 及解的目标函数值
    """
    temp_current = temp_initial  # 当前温度

    x = np.random.permutation(num_city)  # 初始解,编码采用常规的整数编码,如果城市数目为N,那么解就可以表达为1~N的随机排列,
    obj_value = eval_func(x)  # 初始解目标函数值

    global_best = x  # 全局最优解
    trace: List[Tuple[np.ndarray, float]] = [(x, obj_value)]  # 记录每一代最优解, 及解的目标函数值
    while temp_current > temp_final:  # 外循环:退火过程
        for i in range(1000):  # 内循环
            obj_value_old = eval_func(x)
            x_ = two_opt(x)
            obj_value_new = eval_func(x_)
            delta_temp = obj_value_new - obj_value_old
            if delta_temp > 0:
                if np.random.uniform(0, 1) < 1. / np.exp(delta_temp / temp_current):
                    x = x_
            else:
                x = x_
                global_best = x
        trace.append((global_best, eval_func(global_best)))
        temp_current *= alpha

    return trace


def draw(trace: List) -> None:
    iteration = np.arange(len(trace))
    obj_value = [trace[i][1] for i in range(len(trace))]
    plt.plot(iteration, obj_value)
    plt.show()
    final_solution, final_obj_value = trace[-1]
    x = []
    y = []
    for city in final_solution:
        city_x, city_y = city_coordinates[city]
        x.append(city_x)
        y.append(city_y)
    city_x, city_y = city_coordinates[final_solution[0]]
    x.append(city_x)
    y.append(city_y)
    plt.plot(x, y, 'o-', alpha=1, linewidth=2)
    plt.show()


def print_solution(trace: List[Tuple[int, int]]) -> None:
    logging.info(f'城市数量: {num_city}')
    initial_solution, initial_obj_value = trace[0]
    final_solution, final_obj_value = trace[-1]
    logging.info(f'initial solution: {initial_solution}, objective value: {initial_obj_value}')
    logging.info(f'final solution: {final_solution}, objective value: {final_obj_value}')


if __name__ == "__main__":
    city_coordinates = read_dataset()
    num_city = len(city_coordinates)
    distance_matrix: np.ndarray = get_distance_matrix(city_coordinates)
    trace = run_simulated_annealing()
    print_solution(trace)
    draw(trace)

3.3求解结果

程序中有两个算例:
1、 city_coordinates_ ,城市数量为20,本文求解结果目标函数值为911.117353844847;其他文章基于禁忌搜索的TSP问题建模求解(Java)结果为886;基于自适应遗传算法的TSP问题建模求解(Java)为879.0。本文求解结果如下(左图):

INFO:root:城市数量: 20
INFO:root:initial solution: [16  2  9 15  7  3 17 14 19  8 11 12  5  0  4  1 13 10  6 18], objective value: 2040.8676784971715
INFO:root:final solution: [ 1  6 10 13 16 19 12  9 15 18 17 14 11  8  4  0  2  5  7  3], objective value: 911.117353844847

2、 city_coordinates_ att48(TSP问题标准测试函数,城市数量48,最优解为33523)本文求解结果为34974.67245297696(右图):

INFO:root:城市数量: 48
INFO:root:initial solution: [15 22 12 34 24 16 26  3 14  2 27 11 10  0 39  5  4 42 19 44 47 18 28 41  31 36 35 20 43 45 30 46  7 13 33 29  1 23 32 40 38  8 21  9  6 25 37 17], objective value: 162186.17660670803
INFO:root:final solution: [26 18 36  5 27  6 17 43 30 37  8  7  0 39  2 21 15 40 33 13 24 47  4 28 1 41  9 44 34  3 25 23 31 38 20 46 12 22 10 11 14 19 32 45 35 29 42 16], objective value: 34974.67245297696
```

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/151002.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕业设计选题推荐-二手交易跳蚤市场微信小程序/安卓APP-项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

EMNLP 2023 | DeepMind提出大模型In-Context Learning的可解释理论框架

论文题目&#xff1a;In-Context Learning Creates Task Vectors 论文链接&#xff1a;https://arxiv.org/abs/2310.15916 01. 引言 此外&#xff0c;作者也提到本文的方法与软提示&#xff08;soft-prompt&#xff09;[1]方法类似&#xff0c;soft-prompt也是通过调整大模型内…

Nginx配置开启HTTPS

获取证书文件 Nginx 开启SSL server {listen 443 default ssl;server_name localhost;#charset koi8-r;#access_log logs/host.access.log main;proxy_set_header Host $host;ssl_certificate /usr/local/nginx/cert/server.pem;ssl_certificate_key /usr/local/ngin…

java时间类

一、java时间类为什么这么复杂? java的时间类非常复杂&#xff0c;这是由于jdk1.0到jdk1.1的时间类设计存在缺陷&#xff0c;导致使用不方便&#xff0c;线程不安全等问题&#xff0c;所以在jdk1.8&#xff0c;java又重新加入了一些时间类替换之前的时间类&#xff0c;但是jd…

ExoPlayer架构详解与源码分析(8)——Loader

系列文章目录 ExoPlayer架构详解与源码分析&#xff08;1&#xff09;——前言 ExoPlayer架构详解与源码分析&#xff08;2&#xff09;——Player ExoPlayer架构详解与源码分析&#xff08;3&#xff09;——Timeline ExoPlayer架构详解与源码分析&#xff08;4&#xff09;—…

DNS服务器典型配置

文章目录 安装主程序bind和安全插件bind-root修改主配置文件/etc/named.conf正向解析 安装主程序bind和安全插件bind-root yum install bind-chroot修改主配置文件/etc/named.conf vim /etc/named.conf将listen-on和allow-query的ip或域名换成any 表示为服务器所有的IP地址启…

多svn仓库一键更新脚本分享

之前分享过多git仓库一键更新脚本&#xff0c;本期就分享下svn仓库的一键更新脚本 1、首先需要设置svn为可执行命令行 打开SVN安装程序&#xff0c;选择modify&#xff0c;然后点击 command client tools&#xff0c;安装命令行工具 2、update脚本 echo 开始更新SVN目录&…

【Android 标题文字居中 快速实现】

背景&#xff1a; Android App系统默认setTitle左起展示(图左)&#xff0c;IOS App默认居中展示(图右)。现在美工设计 在Android中标题同样居中显示。 解决&#xff1a; 方案一&#xff1a;(传统方式,比较繁琐) 设置ToolBar样式&#xff0c;内嵌TextView来展示&#xff0c;具…

网络安全准入技术之MAC VLAN

网络准入控制作为主要保障企业网络基础设施的安全的措施&#xff0c;特别是对于中大型企业来说&#xff0c;终端类型多样数量激增、终端管理任务重难度大、成本高。 在这样的一个大背景下&#xff0c;拥有更灵活的动态识别、认证、访问控制等成为了企业网络安全的最核心诉求之…

保姆级教程——pytest【入门篇】

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

【libGDX】初识libGDX

1 前言 libGDX 是一个开源且跨平台的 Java 游戏开发框架&#xff0c;于 2010 年 3 月 11 日推出 0.1 版本&#xff0c;它通过 OpenGL ES 2.0/3.0 渲染图像&#xff0c;支持 Windows、Linux、macOS、Android、iOS、Web 等平台&#xff0c;提供了统一的 API&#xff0c;用户只需要…

数据结构—LinkedList与链表

目录 一、链表 1. 链表的概念及结构 1. 单向或者双向 2. 带头或者不带头 3. 循环或者非循环 二.LinkedList的使用 1.LinkedList概念及结构 2. LinkedList的构造 3. LinkedList的方法 三. ArrayList和LinkedList的区别 一、链表 1. 链表的概念及结构 链表是一种 物理…

开启创造力之门:掌握Vue中Slot插槽的使用技巧与灵感

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、s…

【Ubuntu】设置永不息屏与安装 dconf-editor

方式一、GUI界面进行设置 No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.6 LTS Release: 20.04 Codename: focal打开 Ubuntu 桌面环境的设置菜单。你可以通过点击屏幕右上角的系统菜单&#xff0c;然后选择设置。在设置菜单中&#xff0c;…

弱类型和强类型自定义UDAF函数

目录 使用自带的avg函数弱类型自定义UDAF函数(AVG)强类型自定义UDAF函数(AVG) 弱类型&#xff1a;3.x过期 2.x有 强类型&#xff1a;3.x 2.x没有 使用自带的avg函数 import org.apache.spark.rdd.RDD import org.apache.spark.sql.{DataFrame, SparkSession}object UserDefine…

GD32_ADC采样+DMA多通道扫描传输

GD32_ADC采样DMA多通道扫描传输 文章目录 GD32_ADC采样DMA多通道扫描传输前言一、资源介绍二、原理1.ADC连续扫描模式2.DMA传输3.ADC内部通道 三、配置1.ADC配置2.DMA配置3.注意事项 四、计算1.分压转换2.数据转换 前言 <1>、硬件平台&#xff1a;可运行软件程序的GD32单…

【计算思维】少儿编程蓝桥杯青少组计算思维题考试真题及解析B

STEMA考试-计算思维-U8级(样题) 1.浩浩的左⼿边是&#xff08; &#xff09;。 A.兰兰 B.⻉⻉ C.⻘⻘ D.浩浩 2.2时30分&#xff0c;钟⾯上时针和分针形成的⻆是什么⻆&#xff1f;&#xff08; &#xff09; A.钝⻆ B.锐⻆ C.直⻆ D.平⻆ 3.下⾯是⼀年级同学最喜欢的《⻄游记》…

人工智能基础_机器学习037_多项式回归升维实战4_使用随机梯度下降模型_对天猫双十一销量数据进行预测_拟合---人工智能工作笔记0077

上一节我们使用线性回归模型最终拟合了双十一天猫销量数据,升维后的数据. 我们使用SGDRegressor的时候,随机梯度下降的时候,发现有问题, 对吧,怎么都不能拟合我们看看怎么回事现在 可以看到上面是之前的代码 上面是对数据的准备 这里我们还是修改,使用 poly=PolynomialFeatur…

nodejs+vue电影在线预定与管理系统的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计

通过软件的需求分析已经获得了系统的基本功能需求&#xff0c;根据需求&#xff0c;将电影在线预定与管理系统功能模块主要分为管理员模块。 我国各行各业的发展在信息化浪潮的推动下也在不断进步&#xff0c;尤其是电影产业&#xff0c;在人们生活水平提高的同时&#xff0c;从…

旅拍摄影技巧澳大利亚、韩国旅行攻略

欢迎关注「苏南下」 在这里分享我的旅行和影像创作心得 刚刚在腾讯内部做了一场摄影分享课&#xff1a; 《旅拍摄影技巧&澳大利亚、韩国旅行攻略》 分享了早前去两个国家的一些旅行见闻和摄影心得。我发现&#xff1a;把自己学会的东西整理出来&#xff0c;再告诉给别人这件…