六种图算法的python实现

六种图算法的python实现

1. Prim 算法

基本原理

Prim算法是一种求解最小生成树的贪心算法。所谓最小生成树,就是对于给定的连通图,找到一棵包含所有顶点的树,且树上所有边的权重之和最小。Prim算法从一个顶点开始,每次选择与当前生成树距离最短的顶点加入到生成树中,直到所有顶点都加入为止。

应用场景

Prim算法广泛应用于网络设计、电路设计、道路规划等领域,其中需要找到连接所有点的最小成本路径。例如,在铺设电缆或道路网络中,可以使用Prim算法来找到连接所有地点所需的最小成本路径。

优缺点

优点

  1. Prim算法能够找到全局最优解,即最小生成树。
  2. 适用于稠密图,即边数较多的图。

缺点

  1. 对于稀疏图(边数较少的图),Prim算法可能不是最高效的选择。
  2. Prim算法需要频繁地查找和更新距离,因此在实现上可能需要使用优先队列等数据结构来提高效率。
Python 实现

以下是一个简单的Prim算法的Python实现:

import heapq

def prim(graph):
    # 初始化
    start_node = 'A'  # 可以选择任意节点作为起始节点
    visited = set([start_node])  # 已访问节点的集合
    edges = [
        (cost, start_node, to)
        for to, cost in graph[start_node].items()
    ]  # 初始可选边集合
    heapq.heapify(edges)  # 使用堆来优化查找最小边的过程
    mst = []  # 最小生成树的边
    total_cost = 0  # 最小生成树的总权重

    while edges:
        cost, frm, to = heapq.heappop(edges)  # 弹出权重最小的边
        if to not in visited:  # 如果目标节点未被访问过
            visited.add(to)  # 将其标记为已访问
            mst.append((frm, to, cost))  # 将这条边加入最小生成树
            total_cost += cost  # 更新总权重
            # 将与新加入节点相连且未访问过的节点(及其边)加入堆中
            for to_next, cost2 in graph[to].items():
                if to_next not in visited:
                    heapq.heappush(edges, (cost2, to, to_next))

    return mst, total_cost

# 示例图(以字典形式表示,键为起点,值为一个字典,表示从起点到各个终点的权重)
graph = {
    'A': {'B': 2, 'C': 3},
    'B': {'A': 2, 'C': 1, 'D': 1, 'E': 4},
    'C': {'A': 3, 'B': 1, 'F': 5},
    'D': {'B': 1, 'E': 1},
    'E': {'B': 4, 'D': 1, 'F': 1},
    'F': {'C': 5, 'E': 1, 'G': 1},
    'G': {'F': 1}
}

mst, total_cost = prim(graph)
print("最小生成树的边:", mst)
print("最小生成树的总权重:", total_cost)

原始图:

在这里插入图片描述

最小生成树:

在这里插入图片描述

这个实现使用了优先队列(通过Python的heapq模块实现)来优化查找最小边的过程。注意,这个实现假设图是连通的,且权重都是正数。如果图不连通,或者存在负权重的边,那么这个实现可能不适用。

2. Kruskal 算法

基本原理

Kruskal算法是一种用于查找最小生成树的算法,属于贪心算法的一种。在一个加权无向图中,最小生成树是指一个边集,它能够连接所有的顶点,并且所有边的权值之和最小,而且不包含环。

Kruskal算法的基本思想是:

  1. 将图中的所有边按照权重从小到大排序。
  2. 从最小的边开始,依次选择边,每次选择一条边后,判断这条边是否会与已选择的边形成环。
  3. 如果不会形成环,则将这条边加入到最小生成树中;否则,放弃这条边。
  4. 重复步骤2和3,直到所有的顶点都连接在一起或者所有的边都已被考虑过。
应用场景

Kruskal算法在多个领域有广泛的应用,包括但不限于:

  • 网络设计:在构建计算机网络、电力网络或交通网络时,需要找到连接所有节点的最小成本树。
  • 电路设计:在电子设计中,需要找到连接所有组件的最短电线长度。
优缺点

优点

  • 算法简单易懂,容易实现。
  • 总是能找到全局最优解,即权重和最小的生成树。

缺点

  • 当图中的边数非常多时,排序操作可能会比较耗时。
  • 需要额外的数据结构(如并查集)来检测环的形成,增加了算法的复杂度。
Python 实现

下面是一个简单的Kruskal算法的Python实现,使用了并查集来检测环:

class UnionFind:
    def __init__(self, n):
        self.parent = list(range(n))
    
    def find(self, x):
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]
    
    def union(self, x, y):
        root_x = self.find(x)
        root_y = self.find(y)
        self.parent[root_x] = root_y

def kruskal(graph):
    edges = []
    for u in graph:
        for v, w in graph[u]:
            edges.append((w, u, v))
    edges.sort()  # 按权重排序
    
    uf = UnionFind(len(graph))
    mst = []
    for w, u, v in edges:
        if uf.find(u) != uf.find(v):
            uf.union(u, v)
            mst.append((u, v, w))
    return mst

# 示例图
graph = {
    0: [(1, 7), (2, 9), (5, 14)],
    1: [(0, 7), (2, 10), (3, 15)],
    2: [(0, 9), (1, 10), (3, 11), (5, 2)],
    3: [(1, 15), (2, 11), (4, 6)],
    4: [(3, 6), (5, 9)],
    5: [(0, 14), (2, 2), (4, 9)]
}

mst = kruskal(graph)
print("最小生成树的边:", mst)

原始图:

在这里插入图片描述

最小生成树:

在这里插入图片描述

这个代码示例中,graph是一个字典,表示图的邻接表形式。kruskal函数首先将所有边按照权重排序,然后使用并查集来检测并避免环的形成,最后返回最小生成树的边列表。

3. Floyd-Warshall 算法

基本原理

Floyd-Warshall 算法是一种用于寻找给定加权图中所有顶点对之间最短路径的算法。它适用于带权重的有向图或带权重的无向图,并且可以处理负权重的边,但不能处理含有负权重环的图。

算法的基本思想是通过逐步构建更长的路径来找到最短路径。它使用一个三维数组 dist[k][i][j] 来表示从顶点 i 到顶点 j 的、所有中间顶点来自集合 {0, 1, …, k} 的一条最短路径的权重。最终,当 k 等于图中顶点数量减一时,dist[k][i][j] 就是从 i 到 j 的最短路径长度。

在实际应用中,为了节省空间,通常会将三维数组简化为二维数组,通过逐步更新这个二维数组来记录最短路径。

应用场景

Floyd-Warshall 算法通常用于需要找到图中所有顶点对之间最短路径的场景,例如网络路由选择、社交网络中的最短关系链查找等。

优缺点

优点

  • 算法简单易懂,实现起来较为方便。
  • 能够处理带有负权重的边。
  • 可以一次性计算出所有顶点对之间的最短路径。

缺点

  • 时间复杂度和空间复杂度都是 O(n^3),其中 n 是图中的顶点数。对于大型图来说,这可能是一个问题。
  • 不能处理带有负权重环的图。
Python 实现

以下是一个简单的 Floyd-Warshall 算法的 Python 实现:

def floyd_warshall(graph):
    n = len(graph)
    dist = [[float('inf')] * n for _ in range(n)]

    # 直接从邻接矩阵复制权重到dist矩阵
    for i in range(n):
        for j in range(n):
            dist[i][j] = graph[i][j]
            # 设置对角线上的距离为0,表示节点到自身的距离为0
            if i == j:
                dist[i][j] = 0

    # Floyd-Warshall算法的核心部分
    for k in range(n):
        for i in range(n):
            for j in range(n):
                if dist[i][k] != float('inf') and dist[k][j] != float('inf'):
                    dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
    return dist


# 示例图,使用邻接矩阵表示  
graph = [
    [0, 3, float('inf'), 5],
    [2, 0, float('inf'), 4],
    [float('inf'), 1, 0, float('inf')],
    [float('inf'), float('inf'), 2, 0]
]
print(floyd_warshall(graph))

这个实现中,graph 是一个邻接矩阵,表示图中的边和权重。float('inf') 表示无穷大,用于表示两个顶点之间没有直接连接的情况。

4. Bellman-Ford 算法

基本原理

Bellman-Ford 算法是一种用于在带权图中找出从单一源点到其他所有点的最短路径的算法。它适用于带有负权边的图,这是它与 Dijkstra 算法的一个重要区别。Bellman-Ford 算法的基本思想是对图中的所有边进行松弛操作,逐步逼近最短路径。

算法步骤如下:

  1. 初始化:设置源点到所有其他点的距离为无穷大(或一个非常大的数),源点到自身的距离为 0。
  2. 松弛操作:对所有边进行多次遍历(边的数量减 1 次),每次遍历时,对于图中的每一条边 (u, v),如果当前源点到点 u 的距离加上边 (u, v) 的权重小于源点到点 v 的当前距离,则更新源点到点 v 的距离为更小的值。
  3. 检查负权环:再进行一次边的遍历,如果仍有距离被更新,则说明图中存在负权环,因为在一个没有负权环的图中,最短路径的长度在经过 |V|-1 次松弛操作后就已经确定,其中 |V| 是顶点的数量。
应用场景

Bellman-Ford 算法适用于需要处理带有负权重的图的最短路径问题。例如,在路由选择、网络流优化、交通运输规划等领域中,边的权重可能表示时间、费用或距离,并且可能为负(例如,表示某种形式的“奖励”或“折扣”)。

优缺点

优点

  • 可以处理带有负权重的图。
  • 可以检测出负权环。
  • 算法实现相对简单。

缺点

  • 时间复杂度较高,为 O(|V|*|E|),其中 |V| 是顶点数,|E| 是边数。对于稠密图来说,这可能是一个问题。
  • 在没有负权重的图中,通常不如 Dijkstra 算法高效。
Python 实现

以下是一个简单的 Bellman-Ford 算法的 Python 实现:

class Graph:
    def __init__(self, vertices):
        self.V = vertices
        self.graph = []

    def add_edge(self, u, v, w):
        self.graph.append([u, v, w])

    def bellman_ford(self, src):
        dist = [float('inf')] * self.V
        dist[src] = 0

        # 松弛操作,进行 |V|-1 次
        for _ in range(self.V - 1):
            for u, v, w in self.graph:
                if dist[u] != float('inf') and dist[u] + w < dist[v]:
                    dist[v] = dist[u] + w

        # 检查负权环
        for u, v, w in self.graph:
            if dist[u] != float('inf') and dist[u] + w < dist[v]:
                return "图中存在负权环"

        return dist

# 使用示例
g = Graph(5)
g.add_edge(0, 1, -1)
g.add_edge(0, 2, 4)
g.add_edge(1, 2, 3)
g.add_edge(1, 3, 2)
g.add_edge(1, 4, 2)
g.add_edge(3, 2, 5)
g.add_edge(3, 1, 1)
g.add_edge(4, 3, -3)

print(g.bellman_ford(0))  # 输出从顶点 0 到其他各顶点的最短距离

这个实现创建了一个简单的图数据结构,并实现了 Bellman-Ford 算法来查找从指定源点到所有其他点的最短路径。注意,如果图中存在负权环,算法会返回相应的提示信息。

5. 强连通分量算法

基本原理

强连通分量算法主要用于在有向图中找出强连通分量。强连通分量是指在有向图中,任意两个顶点之间都存在一条路径,即它们是相互可达的。常见的强连通分量算法有Kosaraju算法和Tarjan算法。

这里,我们主要介绍Kosaraju算法,其基本原理是通过两次深度优先搜索(DFS)来找到强连通分量。

  1. 第一次DFS:对原始图进行深度优先搜索,并记录每个节点的完成时间(即DFS遍历结束时的时间)。

  2. 计算转置图:将原始图的所有边反向,得到转置图。

  3. 第二次DFS:根据第一次DFS记录的节点完成时间进行降序排序,然后按照这个顺序对转置图进行DFS。每次DFS遍历得到的子图就是一个强连通分量。

应用场景

强连通分量算法常用于社交网络分析、网页链接分析、程序控制流图分析等领域,用于找出紧密相关的群体或模块。

优缺点

优点

  • 能够准确地找出有向图中的强连通分量。
  • Kosaraju算法相对直观,易于理解。

缺点

  • 需要进行两次DFS,时间复杂度相对较高。
  • 需要额外的空间来存储转置图和节点的完成时间。
Python实现(Kosaraju算法)
from collections import defaultdict


class Graph:
    def __init__(self, vertices):
        self.V = vertices
        self.graph = defaultdict(list)

    def addEdge(self, u, v):
        self.graph[u].append(v)

    def DFSUtil(self, v, visited):
        visited.add(v)
        print(v, end='')
        for i in self.graph[v]:
            if i not in visited:
                self.DFSUtil(i, visited)

    def fillOrder(self, v, visited, stack):
        visited.add(v)
        for i in self.graph[v]:
            if i not in visited:
                self.fillOrder(i, visited, stack)
        stack.append(v)  # 修正这里,不要重新赋值给 stack

    def getTranspose(self):
        g = Graph(self.V)
        for i in self.graph:
            for j in self.graph[i]:
                g.addEdge(j, i)
        return g

    def printSCCs(self):
        stack = []
        visited = set()
        for i in range(self.V):
            if i not in visited:
                self.fillOrder(i, visited, stack)
        gr = self.getTranspose()
        visited = set()
        while stack:
            i = stack.pop()
            if i not in visited:
                gr.DFSUtil(i, visited)
                print()


# 使用示例
g = Graph(5)
g.addEdge(1, 0)
g.addEdge(0, 2)
g.addEdge(2, 1)
g.addEdge(0, 3)
g.addEdge(3, 4)
print("强连通分量为:")
g.printSCCs()

注意:上述代码是一个简化的示例,用于说明Kosaraju算法的基本原理。在实际应用中,可能需要根据具体需求进行适当的修改和优化。

这个Python实现中,Graph类表示一个有向图,addEdge方法用于添加边,DFSUtil方法用于执行深度优先搜索,fillOrder方法用于第一次DFS并记录节点的完成时间(通过栈的顺序隐式表示),getTranspose方法用于计算转置图,printSCCs方法用于找出并打印所有的强连通分量。

6. 拓扑排序算法

基本原理

拓扑排序(Topological Sorting)是针对有向无环图(DAG, Directed Acyclic Graph)的顶点的一种排序,它将有向无环图的顶点以线性序列的方式输出,对于每一条有向边 (u, v),顶点 u 在排序中都出现在顶点 v 之前。拓扑排序常用于任务调度、制定课程学习计划等场景。

拓扑排序的基本原理是通过不断移除入度为0的节点(即没有前驱或依赖的节点),并更新其相邻节点的入度,直到所有节点都被移除或者无法再移除入度为0的节点为止。如果还有剩余节点,则说明图中存在环,无法进行拓扑排序。

应用场景
  1. 任务调度:在项目管理中,常常需要确定任务的执行顺序,拓扑排序可以帮助确定哪些任务可以并行执行,哪些任务必须等待其他任务完成后才能开始。
  2. 制定学习计划:在学习多门有依赖关系的课程时,拓扑排序可以帮助规划学习顺序。
  3. 编译器中的指令重排:在编译器优化中,拓扑排序可以确保指令以正确的顺序执行,从而提高程序的执行效率。
优缺点

优点

  • 可以有效地确定有依赖关系的任务或操作的执行顺序。
  • 算法相对简单,容易实现。

缺点

  • 仅适用于有向无环图(DAG),如果图中存在环,则算法无法得出结果。
  • 拓扑排序的结果不唯一,因为可能存在多个入度为0的节点,这些节点的处理顺序可以不同。
Python实现

以下是一个简单的拓扑排序的Python实现:

from collections import defaultdict, deque


def topological_sort(graph):
    # 统计入度
    indegree = defaultdict(int)
    for node in graph:
        for neighbor in graph[node]:
            indegree[neighbor] += 1

    # 将入度为0的节点加入队列
    queue = deque([node for node in graph if indegree[node] == 0])
    result = []

    # 拓扑排序
    while queue:
        node = queue.popleft()
        result.append(node)
        # 将该节点的邻接节点的入度减1,并将入度为0的节点加入队列
        for neighbor in graph[node]:
            indegree[neighbor] -= 1
            if indegree[neighbor] == 0:
                queue.append(neighbor)

    # 如果结果中的节点数等于图中的节点数,则拓扑排序成功
    if len(result) == len(graph):
        return result
    else:
        return None


# 测试
graph = {
    'A': ['B', 'C'],
    'B': ['D', 'E'],
    'C': ['F'],
    'D': [],
    'E': ['F'],
    'F': []
}

sorted_nodes = topological_sort(graph)
if sorted_nodes:
    print("拓扑排序结果:", sorted_nodes)
else:
    print("图中存在环,无法进行拓扑排序")

这个示例中,graph是一个字典,表示有向图的结构,其中键是节点,值是该节点的相邻节点列表。topological_sort函数接受这个图结构作为输入,并返回一个可能的拓扑排序结果列表。如果图中存在环,则返回相应的错误信息。

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

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

相关文章

数据丢失?揭秘easyrecovery破解版下载安装步骤教程,一键恢复!

“我不小心把硬盘里的重要文件删了&#xff0c;怎么都找不到了&#xff01;” “电脑突然崩溃了&#xff0c;所有的数据都没了&#xff0c;怎么办&#xff1f;” 这些情况是不是让你感到绝望&#xff1f;不过别担心&#xff0c;EasyRecovery数据恢复软件可以帮你轻松解决这些问…

[office] excel表格中双击鼠标左键有什么快捷作用- #经验分享#媒体

excel表格中双击鼠标左键有什么快捷作用? excel表格中双击鼠标左键有什么快捷作用&#xff1f;不要小看鼠标左键双击的作用&#xff0c;在excel中双击鼠标左键可以实现六个功能&#xff0c;提高工作效率&#xff0c;到底是那六个功能呢&#xff1f;请看下文详细介绍 在表格中…

R语言绘图 --- 桑基图(Biorplot 开发日志 --- 5)

「写在前面」 在科研数据分析中我们会重复地绘制一些图形&#xff0c;如果代码管理不当经常就会忘记之前绘图的代码。于是我计划开发一个 R 包&#xff08;Biorplot&#xff09;&#xff0c;用来管理自己 R 语言绘图的代码。本系列文章用于记录 Biorplot 包开发日志。 相关链接…

React基础教程:TodoList案例

todoList案例——增加 定义状态 // 定义状态state {list: ["kevin", "book", "paul"]}利用ul遍历list数组 <ul>{this.state.list.map(item ><li style{{fontWeight: "bold", fontSize: "20px"}} key{item.i…

MoE大模型大火,AI厂商们在新架构上看到了什么样的未来?

文 | 智能相对论 作者 | 陈泊丞 很久以前&#xff0c;在一个遥远的国度里&#xff0c;国王决定建造一座宏伟的宫殿&#xff0c;以展示国家的繁荣和权力。他邀请了全国最著名的建筑师来设计这座宫殿&#xff0c;这个人以其卓越的才能和智慧闻名。 然而&#xff0c;这位建筑师…

Apollo9.0 PNC源码学习之Control模块(三)

本文将对Apollo的纵向控制器进行讲解&#xff0c;看完本文&#xff0c;你将会对百度Apollo的纵向控制有更深的理解 前面文章&#xff1a; Apollo9.0 PNC源码学习之Control模块&#xff08;一&#xff09; Apollo9.0 PNC源码学习之Control模块&#xff08;二&#xff09; 1 纵向…

AI大模型的战场:通用与垂直的较量

AI大模型的战场&#xff1a;通用与垂直的较量 引言&#xff1a;AI界的“通才”与“专家” 在AI的大千世界里&#xff0c;有这样两类模型&#xff1a;一类是像瑞士军刀一样多功能的通用大模型&#xff0c;另一类则是像手术刀一样精准的垂直大模型。它们在AI战场上展开了一场激…

【0基础学爬虫】爬虫基础之自动化工具 DrissionPage 的使用

概述 前三期文章中已经介绍到了 Selenium 与 Playwright 、Pyppeteer 的使用方法&#xff0c;它们的功能都非常强大。而本期要讲的 DrissionPage 更为独特&#xff0c;强大&#xff0c;而且使用更为方便&#xff0c;目前检测少&#xff0c;强烈推荐&#xff01;&#xff01;&a…

GaN VCSEL:改进生产工艺

对腔体厚度的卓越控制宛如一位精准的狙击手&#xff0c;精确锁定了发射波长的目标。日本工程师们凭借一项革命性的工艺&#xff0c;成功打造出效率极高的VCSEL&#xff0c;其发射波长与目标波长如丝般顺滑地接近。 这一卓越的进步是名城大学与国家先进工业科学和技术研究所科研…

阿里云物联网平台案例教程

1、定义&#xff1a; ​ 物联网&#xff08;简称IOT&#xff09;把任何物体与物联网相连接&#xff0c;进行消息的交换和通信&#xff0c;实现对物品的智能化识别。简单说是&#xff1a;物联网就是把所有的物体连接起来相互作用&#xff0c;形成一个互联互通的网络&#xff0c…

解读光纤模块的参数有哪些

光模块的具体参数有传输速率、传输距离、中心波长、光纤类型、光口类型、工作温度范围、最大功耗等。下面给大家详解一下各个参数的作用 因为光纤本身对光信号有色散、损耗等副作用。因此不同类型的光源发出的光所能传输的距离不一样。对接光接口时&#xff0c;应根据最远的信号…

【架构之路】微服务中常用的几种通信方式

2024年&#xff0c;计算机相关专业还值得选择吗&#xff1f; 强烈推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站:人工智能 引言 微服务架构由于其灵活性、高可扩展性和易维护性&am…

Redis脑裂问题详解及解决方案

Redis脑裂问题 Redis脑裂问题是指在主从集群中同时存在两个主节点&#xff0c;这会导致不同客户端往不同的主节点写入数据&#xff0c;最终导致数据不一致&#xff0c;甚至数据丢失。 哨兵主从集群脑裂 场景描述 假设有三台服务器&#xff1a;一台主服务器&#xff0c;两台…

对Java中二维数组的深层认识

首先&#xff0c;在JAVA中&#xff0c;二维数组是一种数组的数组。它可以看作是一个矩阵&#xff0c;通常是由于表示二维数据节后&#xff0c;如表格和网格。 1.声明和初始化二维数组 声明 int[][] arr;初始化 int[][] arrnew int[3][4];或者用花括号嵌套 int[][] arr{{1,…

高温预警,快收下这份机房运维攻略

高温预警 华东区即将迎来最强高温&#xff0c;根据历史经验&#xff0c;数据机房在夏季高温环境导致设备温度过高&#xff0c;宕机事件明显增加&#xff0c;为保障系统健康稳定运行&#xff0c;需要针对数据机房空调、设备的运行状态及环境进行检查&#xff0c;并同时期开展防尘…

[Shell编程学习路线]--shell中重定向和管道符(详细介绍)

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f6e0;️Shell编程专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年6月12日10点50分 &#x1f004;️文章质量&#xff1a;93分 ——前言—— 在Shell编程中&#xff0c;重定向和管道符是两个…

MySQL 示例数据库大全

前言&#xff1a; 我们练习 SQL 时&#xff0c;总会自己创造一些测试数据或者网上找些案例来学习&#xff0c;其实 MySQL 官方提供了好几个示例数据库&#xff0c;在 MySQL 的学习、开发和实践中具有非常重要的作用&#xff0c;能够帮助初学者更好地理解和应用 MySQL 的各种功…

内行都在学的大模型黑书!外网爆火LLM手册

前言 在人工智能的浪潮中&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域正经历着前所未有的变革。而在这场变革中&#xff0c;Transformer架构无疑成为了最引人瞩目的明星。作为对Transformer工作原理充满好奇的你&#xff0c;是否渴望深入了解这一技术的奥秘&…

Flutter基础 -- Flutter常用组件

目录 1. 文本组件 Text 1.1 基础用法 1.2 Text 定义 1.3 Text 示例 1.4 Text.rich、RichText 、TextSpan 1.5 RichText 示例 2. 导入资源 2.1 加入资源 2.2 加入图片 3. 图片组件 image 3.1 colorBlendMode 混合参数 3.2 fit 图片大小适配 3.3 ImageProvider 图片…

AI开发基础1-操作系统

这里介绍AI服务器开发所需的必要操作系统知识 1.文件系统 理论基础是《操作系统》&#xff0c;再深入些是《计算机组成原理》 目的是管理操作系统&#xff0c;核心是文件系统, 通过命令行操作 路径是文件系统中用来指示文件或目录位置的描述。 1.1 绝对路径 (Absolute Path)…