代码随想录训练营 Day60打卡 图论part10 SPFA算法 Bellman-Ford 之判断负权回路 Bellman-Ford 之单源有限最短路

news2024/11/15 11:54:22

代码随想录训练营 Day60打卡 图论part10

一、Bellman_ford 队列优化算法(又名SPFA)

例题:卡码94. 城市间货物运输 I

题目描述
某国为促进城市间经济交流,决定对货物运输提供补贴。共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。
网络中的道路都有各自的运输成本和政府补贴,道路的权值计算方式为:运输成本 - 政府补贴。权值为正表示扣除了政府补贴后运输货物仍需支付的费用;权值为负则表示政府的补贴超过了支出的运输成本,实际表现为运输过程中还能赚取一定的收益。
请找出从城市 1 到城市 n 的所有可能路径中,综合政府补贴后的最低运输成本。如果最低运输成本是一个负数,它表示在遵循最优路径的情况下,运输过程中反而能够实现盈利。
城市 1 到城市 n 之间可能会出现没有路径的情况,同时保证道路网络中不存在任何负权回路。
输入描述
第一行包含两个正整数,第一个正整数 n 表示该国一共有 n 个城市,第二个整数 m 表示这些城市中共有 m 条道路。
接下来为 m 行,每行包括三个整数,s、t 和 v,表示 s 号城市运输货物到达 t 号城市,道路权值为 v (单向图)。
输出描述
如果能够从城市 1 到连通到城市 n, 请输出一个整数,表示运输成本。如果该整数是负数,则表示实现了盈利。如果从城市 1 没有路径可达城市 n,请输出 “unconnected”。
输入示例
6 7
5 6 -2
1 2 1
5 3 1
2 5 2
2 4 -3
4 6 4
1 3 5
输出示例
1
提示信息

示例中最佳路径是从 1 -> 2 -> 5 -> 6,路上的权值分别为 1 2 -2,最终的最低运输成本为 1 + 2 + (-2) = 1。
示例 2:
4 2
1 2 -1
3 4 -1
在此示例中,无法找到一条路径从 1 通往 4,所以此时应该输出 “unconnected”。

SPFA(Shortest Path Faster Algorithm)是一种 Bellman-Ford 算法的队列优化版本。它的主要思想是:使用一个队列来保存已经更新过的节点,并且仅对这些节点进行松弛操作,而不是对所有边进行松弛,从而加速最短路径的计算。这样可以减少不必要的松弛操作。

算法流程

  1. 初始化距离数组,将起点的距离设为 0,其他节点的距离设为正无穷大。 将起点加入队列。
  2. 每次从队列中取出一个节点,遍历与该节点相连的所有边,如果可以进行松弛,则更新相邻节点的最短路径,并将该相邻节点加入队列(如果它不在队列中的话)。
  3. 重复步骤 3,直到队列为空。

代码实现

from collections import deque, defaultdict
import sys

# 定义一个边结构,用于存储每条边的信息
class Edge:
    def __init__(self, to, weight):
        self.to = to  # 边的目标节点
        self.weight = weight  # 边的权重

def spfa(n, edges, start, end):
    # 初始化邻接表
    graph = defaultdict(list)
    for p1, p2, val in edges:
        graph[p1].append(Edge(p2, val))

    # 初始化最短距离数组,所有节点的最短距离都为无穷大
    minDist = [sys.maxsize] * (n + 1)
    minDist[start] = 0  # 起点的距离设为0

    # 初始化队列,并将起点加入队列
    queue = deque([start])
    isInQueue = [False] * (n + 1)  # 用于记录节点是否在队列中,避免重复加入
    isInQueue[start] = True

    while queue:
        # 从队列中取出一个节点
        node = queue.popleft()
        isInQueue[node] = False  # 节点取出后取消标记

        # 遍历该节点的所有相邻边,进行松弛操作
        for edge in graph[node]:
            to = edge.to
            weight = edge.weight
            # 如果可以通过 node 到达 to 的更短路径,则更新最短距离
            if minDist[to] > minDist[node] + weight:
                minDist[to] = minDist[node] + weight
                # 如果相邻节点不在队列中,则将其加入队列
                if not isInQueue[to]:
                    queue.append(to)
                    isInQueue[to] = True

    # 如果终点的最短距离仍为无穷大,说明无法到达终点
    if minDist[end] == sys.maxsize:
        print("unconnected")
    else:
        print(minDist[end])  # 输出到终点的最短路径长度

# 输入处理
n, m = map(int, input().split())  # n 是节点数,m 是边数
edges = []
for _ in range(m):
    p1, p2, val = map(int, input().split())  # 输入边信息
    edges.append((p1, p2, val))

start = 1  # 起点设为节点1
end = n    # 终点设为节点n

# 调用SPFA算法
spfa(n, edges, start, end)

详细解释:

  • Edge类:定义了一个边结构,用于存储边的目标节点和边的权重。
  • spfa 函数:这是 SPFA 算法的主体函数,接收节点数 n、边列表 edges、起点 start 和终点 end作为参数,返回从起点到终点的最短路径距离。
    graph:邻接表,用来存储每个节点的相邻边。
    minDist:最短距离数组,初始时所有节点的最短距离都设置为无穷大,起点的最短距离为 0。
    queue:队列,用于存储更新过的节点,起点首先加入队列。
    isInQueue:标记数组,表示当前节点是否在队列中,避免重复入队。
    while 循环:不断从队列中取出节点并进行松弛操作,直到队列为空。
    松弛操作:如果通过某条边可以找到更短路径,则更新目标节点的最短路径,并将其加入队列。
    最终结果:如果终点的最短路径值仍为无穷大,则表示无法到达终点;否则输出终点的最短路径长度。

复杂度分析:

  • 时间复杂度:最坏情况下时间复杂度为 O(V * E),其中 V 为节点数,E 为边数。但由于队列优化,通常性能会比原始的
    Bellman-Ford 更优。
  • 空间复杂度:O(V + E),用来存储图和队列。

SPFA 的优化机制
SPFA 的核心优化思想是只松弛那些可能带来改进的边。它使用队列来跟踪已经发生更新的节点(称为活跃节点),从这些节点出发继续尝试松弛邻接边。这样就避免了对所有边的重复松弛。

关键优化点:

  1. 只松弛有效边:

Bellman-Ford 每一轮都会检查所有边,而 SPFA 只松弛从“活跃节点”出发的边。这意味着在很多情况下,SPFA 需要松弛的边数量会远小于 Bellman-Ford 的所有边。

  1. 跳过不活跃节点:

只有当某个节点的最短路径被更新时,SPFA 才会将它的相邻节点加入队列。因此,如果某些节点的路径没有更新,它们不会被加入队列进行松弛操作。

  1. 动态松弛顺序:

Bellman-Ford 是静态的,每一轮都对所有边进行遍历;而 SPFA 是动态的,按需对队列中的节点及其相邻边进行松弛。这种按需松弛会根据路径变化自适应调整执行顺序,减少无效计算。

时间复杂度分析

  1. 最坏情况:

    在最坏情况下,SPFA 可能需要对每条边执行 𝑉次松弛操作,这样最坏情况下的时间复杂度仍然是:𝑂(𝑉×𝐸)
    这与 Bellman-Ford 算法在最坏情况下一样。

  2. 平均情况:

    在许多实际应用中,SPFA 通常可以在远少于 𝑉−1 轮迭代的情况下收敛。这是因为一旦最短路径收敛,队列中的节点数量会迅速减少,因此减少了不必要的松弛操作。对于稀疏图(边较少)和具有良好结构的图,SPFA 的平均时间复杂度更接近于线性:𝑂(𝐸) 。
    也就是只需对每条边松弛一次或几次即可收敛。

卡码题目链接
题目文章讲解

二、Bellman-Ford 之判断负权回路

例题:卡码94. 城市间货物运输 I

题目描述
某国为促进城市间经济交流,决定对货物运输提供补贴。共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。
网络中的道路都有各自的运输成本和政府补贴,道路的权值计算方式为:运输成本 - 政府补贴。权值为正表示扣除了政府补贴后运输货物仍需支付的费用;权值为负则表示政府的补贴超过了支出的运输成本,实际表现为运输过程中还能赚取一定的收益。
然而,在评估从城市 1 到城市 n 的所有可能路径中综合政府补贴后的最低运输成本时,存在一种情况:图中可能出现负权回路。负权回路是指一系列道路的总权值为负,这样的回路使得通过反复经过回路中的道路,理论上可以无限地减少总成本或无限地增加总收益。为了避免货物运输商采用负权回路这种情况无限的赚取政府补贴,算法还需检测这种特殊情况。
请找出从城市 1 到城市 n 的所有可能路径中,综合政府补贴后的最低运输成本。同时能够检测并适当处理负权回路的存在。
城市 1 到城市 n 之间可能会出现没有路径的情况
输入描述
第一行包含两个正整数,第一个正整数 n 表示该国一共有 n 个城市,第二个整数 m 表示这些城市中共有 m 条道路。
接下来为 m 行,每行包括三个整数,s、t 和 v,表示 s 号城市运输货物到达 t 号城市,道路权值为 v。
输出描述
如果没有发现负权回路,则输出一个整数,表示从城市 1 到城市 n 的最低运输成本(包括政府补贴)。如果该整数是负数,则表示实现了盈利。如果发现了负权回路的存在,则输出 “circle”。如果从城市 1 无法到达城市 n,则输出 “unconnected”。
输入示例
4 4
1 2 -1
2 3 1
3 1 -1
3 4 1
输出示例
circle
提示信息
路径中存在负权回路,从 1 -> 2 -> 3 -> 1,总权值为 -1,理论上货物运输商可以在该回路无限循环赚取政府补贴,所以输出 “circle” 表示已经检测出了该种情况。

Bellman-Ford 算法是一种用于寻找图中单源最短路径的算法,允许图中存在负权边,但不能处理图中存在负权回路的情况。在 Bellman-Ford 算法中,松弛每条边 n-1 次(n 是节点数)可以确保找到从起点到所有其他节点的最短路径。如果在第 n 次松弛后仍然发生了变化,说明图中存在负权回路。

负权回路的影响

在本题中,由于存在负权回路,我们可以在回路中绕圈,继续减小路径的代价,导致最短路径可以无限减小。这意味着存在负权回路的图是没有最小路径解的,因为可以通过绕圈使路径代价无限减少。因此,解决本题的关键在于:在执行完 n-1 次松弛之后,再执行第 n 次松弛,如果最短路径数组 minDist 仍然发生变化,则说明存在负权回路。

思路总结

  1. 初始化:从起点到其他所有节点的距离初始化为无穷大(inf),到起点自身的距离为 0。
  2. 松弛过程:对所有边进行 n-1 次松弛操作,确保找到从起点到其他节点的最短路径。
  3. 判断负权回路:在第 n 次松弛时,如果距离数组发生变化,则说明图中存在负权回路。

代码实现

import sys

def main():
    input = sys.stdin.read
    data = input().split()
    index = 0
    
    # 读取节点数 n 和边数 m
    n = int(data[index])
    index += 1
    m = int(data[index])
    index += 1
    
    # 记录所有的边,grid 是一个包含 [p1, p2, val] 的列表,表示从 p1 到 p2,权值为 val
    grid = []
    for i in range(m):
        p1 = int(data[index])
        index += 1
        p2 = int(data[index])
        index += 1
        val = int(data[index])
        index += 1
        grid.append([p1, p2, val])

    start = 1  # 起点是节点 1
    end = n    # 终点是节点 n

    # minDist 数组存储起点到每个节点的最短距离,初始为无穷大
    minDist = [float('inf')] * (n + 1)
    minDist[start] = 0  # 起点到自身的距离为 0
    flag = False  # 用于标记是否有负权回路

    # 松弛 n 次,前 n-1 次是正常的 Bellman-Ford 松弛,第 n 次用于检查负权回路
    for i in range(1, n + 1):  # 从 1 到 n,松弛 n 次
        for side in grid:
            from_node = side[0]  # 边的起点
            to = side[1]         # 边的终点
            price = side[2]      # 边的权值
            
            # 如果松弛次数小于 n 次,正常松弛
            if i < n:
                # 如果起点到 from_node 的距离不是无穷大,且通过 from_node 能到达 to,并且能更新到更小的距离,则进行松弛
                if minDist[from_node] != float('inf') and minDist[to] > minDist[from_node] + price:
                    minDist[to] = minDist[from_node] + price
            else:
                # 第 n 次松弛,用于检查是否存在负权回路
                if minDist[from_node] != float('inf') and minDist[to] > minDist[from_node] + price:
                    flag = True  # 如果还能松弛,说明存在负权回路

    # 如果存在负权回路
    if flag:
        print("circle")
    # 如果起点和终点不连通,即终点的最短路径还是无穷大
    elif minDist[end] == float('inf'):
        print("unconnected")
    else:
        # 否则输出起点到终点的最短路径
        print(minDist[end])

if __name__ == "__main__":
    main()

卡码题目链接
题目文章讲解

三、Bellman-Ford 之单源有限最短路

例题:卡码96. 城市间货物运输 III

题目描述
某国为促进城市间经济交流,决定对货物运输提供补贴。共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。
网络中的道路都有各自的运输成本和政府补贴,道路的权值计算方式为:运输成本 - 政府补贴。权值为正表示扣除了政府补贴后运输货物仍需支付的费用;权值为负则表示政府的补贴超过了支出的运输成本,实际表现为运输过程中还能赚取一定的收益。
请计算在最多经过 k 个城市的条件下,从城市 src 到城市 dst 的最低运输成本。
输入描述
第一行包含两个正整数,第一个正整数 n 表示该国一共有 n 个城市,第二个整数 m 表示这些城市中共有 m 条道路。
接下来为 m 行,每行包括三个整数,s、t 和 v,表示 s 号城市运输货物到达 t 号城市,道路权值为 v。
最后一行包含三个正整数,src、dst、和 k,src 和 dst 为城市编号,从 src 到 dst 经过的城市数量限制。
输出描述
输出一个整数,表示从城市 src 到城市 dst 的最低运输成本,如果无法在给定经过城市数量限制下找到从 src 到 dst 的路径,则输出 “unreachable”,表示不存在符合条件的运输方案。
输入示例
6 7
1 2 1
2 4 -3
2 5 2
1 3 5
3 5 1
4 6 4
5 6 -2
2 6 1
输出示例
0
提示信息
从 2 -> 5 -> 6 中转一站,运输成本为 0。

本题是 Bellman-Ford 算法的一个变种,需要计算从起点到终点,**最多经过 k 个城市(即 k + 1 条边)**的最短路径。核心思想和 Bellman-Ford 算法类似,不同之处在于我们需要限制松弛操作的次数,即最多只松弛 k + 1 次。

问题背景

  • 每次松弛操作,相当于对所有边进行一次松弛,尝试更新当前已知的最短路径。
  • 在标准的 Bellman-Ford 中,我们对所有边松弛 n-1 次即可得到从起点到所有其他节点的最短路径,其中 n
    是节点数量,因为最长路径最多经过 n-1 条边。
  • 而在本题中,我们只需要考虑最多经过 k + 1 条边的路径,因此只需松弛 k + 1 次。

问题关键
在松弛过程中,更新节点的距离时,我们要基于上一次松弛后的最短路径来进行更新。因此,每次松弛时要基于前一次的结果(即 minDist_copy 数组)进行更新,而不是当前的结果。

思路总结

  1. 初始化 minDist 数组,表示从起点到各个节点的最短路径,起点到自身距离为 0,其他节点初始化为无穷大(表示不可达)。
  2. 松弛 k + 1 次,每次松弛时基于上一次松弛的结果更新最短路径。
  3. 在松弛结束后,如果终点的最短路径依然为无穷大,说明不可达,输出 “unreachable”。否则输出最短路径。

代码实现

import sys

def main():
    input = sys.stdin.read
    data = input().split()
    
    # 读取节点数 n 和边数 m
    index = 0
    n = int(data[index])
    index += 1
    m = int(data[index])
    index += 1
    
    # 读取边信息 (p1, p2, val)
    grid = []
    for i in range(m):
        p1 = int(data[index])
        index += 1
        p2 = int(data[index])
        index += 1
        val = int(data[index])
        index += 1
        grid.append([p1, p2, val])
    
    # 读取起点 src,终点 dst,最多经过的节点数 k
    src = int(data[index])
    index += 1
    dst = int(data[index])
    index += 1
    k = int(data[index])
    index += 1
    
    # 初始化最短路径数组,minDist[src] = 0 表示起点到自身的距离为 0
    minDist = [float('inf')] * (n + 1)
    minDist[src] = 0
    
    # 用来记录上一次遍历的最短路径结果
    minDist_copy = minDist[:]
    
    # 松弛 k + 1 次
    for i in range(k + 1):
        minDist_copy = minDist[:]  # 记录上一次松弛的最短路径结果
        for side in grid:
            from_node = side[0]
            to_node = side[1]
            price = side[2]
            # 如果 from_node 可达,并且可以更新到更短的路径,更新 minDist
            if minDist_copy[from_node] != float('inf') and minDist[to_node] > minDist_copy[from_node] + price:
                minDist[to_node] = minDist_copy[from_node] + price
    
    # 输出结果
    if minDist[dst] == float('inf'):
        print("unreachable")  # 如果终点不可达,输出 unreachable
    else:
        print(minDist[dst])   # 否则输出起点到终点的最短路径

if __name__ == "__main__":
    main()

  • 时间复杂度:本算法的时间复杂度为 O(k * m),其中 k 是松弛次数,m 是图中边的数量。相较于标准的 Bellman-Ford 算法时间复杂度 O(n * m),这是合理的限制条件,因为我们只松弛 k + 1 次。
  • 空间复杂度:主要存储 minDist 和 minDist_copy 两个数组,空间复杂度为 O(n)。

卡码题目链接
题目文章讲解

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Monster Sound FX Pack 2 怪物恶魔野兽声效包

这是受最新电影和游戏启发而创作的一系列超凡怪兽音效中的第二卷。Monster Sound FX Pack 2 包含精心设计的声音,充满个性,为听众带来新的体验。这些声音经过专业设计,是严肃的声音设计师和游戏开发者的必备品! 发现声音非常适合龙、野兽、外星人、兽人、地精、巨人、巨魔、…

【Qt笔记】QScrollArea控件详解

目录 引言 一、QScrollArea 的基本概念 二、QScrollArea 的主要属性 2.1 设置内容大小是否随滚动区域变化 2.2 设置水平与垂直滚动条 2.3 设置视口外边距 三、QScrollArea 的常用方法 3.1 设置显示小部件 3.2 返回当前设置的小部件 3.3 设置内部小部件是否可以填充…

基于51单片机的16X16点阵显示屏proteus仿真

地址&#xff1a; https://pan.baidu.com/s/1JQ225NSKweqf1Zlad_f1Mw 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectro…

ZW3D二次开发_UI_非模板表单_设置表单显示位置

1.ZW3D弹出非模板表单时可以设置弹出位置&#xff08;居中、左下角、右上角等&#xff09; 2.假设已创建好非模板表单 3.在Form属性中添加form_pos属性 4.输入值 base,CTR,0.0 &#xff0c;如下图 也可以设置为其他值显示在不同的位置&#xff0c;如下 5.重新编译&#xff0c;…

宏电5G工业互联网解决方案荣获第七届“绽放杯”5G应用征集大赛5G应用融合产品专题赛优秀奖。

近日&#xff0c;“宏电5G工业互联网解决方案赋能传统企业数字化转型升级”项目荣获第七届“绽放杯”5G应用征集大赛5G应用融合产品专题赛优秀奖。 “绽放杯”由中国信息通信研究院及三大运营商共同主办&#xff0c;是国内最具影响力的全国性5G应用赛事&#xff0c;本次“绽放…

大数据-136 - ClickHouse 集群 表引擎详解1 - 日志、Log、Memory、Merge

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

《深入理解 Java 中的多线程基础(篇一)》

多线程基础 概述 现代操作系统&#xff08;Windows&#xff0c;macOS&#xff0c;Linux&#xff09;都可以执行多任务。多任务就是同时运行多个任务。 例如&#xff1a;播放音乐的同时&#xff0c;浏览器可以进行文件下载&#xff0c;同时可以进行QQ消息的收发。 CPU执行代码…

发展与监管协同发力 人工智能算法领域已形成良好生态

发展与监管协同发力 人工智能算法领域已形成良好生态 近日&#xff0c;全国组织机构统一社会信用代码数据服务中心对国家网信办公示的人工智能领域备案信息进行了详尽的分析&#xff0c;揭示了我国人工智能产业的蓬勃景象。据统计&#xff0c;我国人工智能领域的备案主体遍布各…

uni-app生命周期(三)

文章目录 一、uni-app的生命周期二、应用生命周期三、页面的生命周期函数1.简介2.页面加载时序介绍3.页面加载常见问题4.页面加载顺序4.部分生命周期介绍 四、组件的生命周期函数 一、uni-app的生命周期 应用生命周期&#xff08;整个App的生命周期&#xff09; 在app.vue里面…

认知杂谈61《天呐!“稳住,别浪” 竟藏着改变人生的惊天秘密,不看后悔一辈子!》

内容摘要&#xff1a; 生活要耐心&#xff0c;记住 “稳住&#xff0c;别浪”。遇难关别慌&#xff0c;如考教资、学平面设计等&#xff0c;一步步来。保护名声与人脉&#xff0c;多交靠谱朋友。越乱越要静&#xff0c;困难时冷静分析。培养耐心&#xff0c;认识天性、明确预算…

多个系统运维压力大?统一运维管理为IT轻松解忧

企业基于网络安全管理需要&#xff0c;采用防火墙、网闸、云桌面等多种方式进行网络隔离&#xff0c;网络隔离后&#xff0c;数据仍需在不同网络区域间流转&#xff0c;此时便产生了网间数据摆渡需求。为了业务有序正常开展&#xff0c;同时保证严密的网络隔离架构不受破坏&…

云曦2024秋季学期开学考复现

Web 学习高数 资料&#xff1a;命令执行中关于PHP正则表达式的一些绕过方法_正则表达式中过滤的怎么绕过-CSDN博客 记 [CISCN 2019 初赛]Love Math三种解法-CSDN博客 WEB攻防-RCE代码&命令执行&过滤绕过&异或无字符&无回显方案&黑白盒挖掘_代码执行 异…

Snowflake 如何通过 Apache Iceberg 和 Polaris 为大数据的未来提供动力

Snowflake 的使命是让每个组织都成为数据驱动型组织。凭借围绕 Apache Iceberg 的最新创新和 Polaris 的推出,这家数据云公司使开发人员、工程师和架构师能够比以往任何时候都更快、更轻松地利用大数据获得变革性的业务见解。 将开放标准引入数据云 Snowflake 战略的核心是采…

提升RAG系统的回答质量:高质量文档解析终极干货

为什么RAG系统重点解析PDF&#xff1f; 在RAG系统中&#xff0c;PDF文档成为重点解析对象的原因与其在企业中的广泛应用以及其自身的优势密切相关。 PDF文档在企业中的普遍使用 行业标准格式&#xff1a;PDF&#xff08;可移植文档格式&#xff09;是各行业用来分发和保存数…

抓机遇,创发展︱2025 第十二届广州国际汽车零部件加工技术及汽车模具展览会,零部件国产浪潮不可阻挡

抓机遇&#xff0c;创发展︱2025 第十二届广州国际汽车零部件加工技术及汽车模具展览会&#xff0c;零部件国产浪潮不可阻挡 汽车零部件行业是汽车工业发展的基础&#xff0c;是支撑汽车工业持续稳步发展前提条件。随着经济全球化和市场一体化进程的推进&#xff0c;汽车零部件…

【devops】devops-git之git分支与标签使用

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

Python画笔案例-047 绘制雪花

1、绘制雪花 通过 python 的turtle 库绘制 雪花&#xff0c;如下图&#xff1a; 2、实现代码 绘制 雪花&#xff0c;以下为实现代码&#xff1a; """雪花.py """ import turtledef draw_branch(d):for _ in range(2):turtle.fd(d)turtle.lt(45)…

实时分析都靠它→揭秘YashanDB列式存储引擎的技术实现

01 概述 YashanDB列式存储引擎&#xff0c;又称为LSC&#xff08;Large-scale Storage Columnar Table)。其通过自研的CBO优化器、向量化执行、原生列存格式等技术&#xff0c;达到业界领先的查询分析能力。 YashanDB LSC是专为海量数据的实时分析场景而设计&#xff0c;致力…

vue3 动态 svg 图标使用

前言 在做后台管理系统中,我们经常会用到很多图标,比如左侧菜单栏的图标 当然这里 element-ui 或者 element-plus 组件库都会提供图标 但是在有些情况下 element-ui 或者 element-plus 组件库提供的图标满足不了我们的需求时,这个时候我们就需要自己去网上找一些素材或者…

逆向学习系列(三)adb的使用

由于是记录学习&#xff0c;我就用结合自己的理解&#xff0c;用最通俗的语言进行讲解。 adb是android debug bridge的简写&#xff0c;其作用就是将电脑和手机相连接&#xff0c;用电脑控制手机。 一、adb哪里来 我使用的adb一般都是安装模拟器的时候&#xff0c;模拟器自带…