【人工智能离散数学基础】——深入详解图论:基础图结构及算法,应用于图神经网络等

深入详解图论:基础图结构及算法,应用于图神经网络等

        图论(Graph Theory)是数学中研究图这种离散结构的分支,广泛应用于计算机科学、网络分析、人工智能等领域。随着图神经网络(Graph Neural Networks, GNNs)在深度学习中的兴起,图论的基础知识和算法在处理复杂数据结构和关系时显得尤为重要。本文将深入探讨图论的基础图结构及算法,并详细介绍其在图神经网络中的应用。

目录

  1. 引言
  2. 基础图结构
    • 图的定义
    • 图的分类
    • 图的表示方法
    • 特殊类型的图
  3. 基本图算法
    • 图遍历算法
      • 深度优先搜索(DFS)
      • 广度优先搜索(BFS)
    • 最短路径算法
      • Dijkstra算法
      • Bellman-Ford算法
      • Floyd-Warshall算法
    • 最小生成树算法
      • Kruskal算法
      • Prim算法
    • 拓扑排序
    • 强连通分量
  4. 图论在图神经网络中的应用
    • 图神经网络概述
    • 图卷积网络(GCN)
    • 图注意力网络(GAT)
    • 应用案例
  5. 示例代码
    • 使用NetworkX进行图的构建与算法实现
    • 简单图神经网络的实现
  6. 总结与展望
  7. 参考资料

1. 引言

        图论作为数学的一个重要分支,研究对象为图这一抽象概念。图由节点(顶点)和连接节点的边组成,能够有效表示实体之间的各种关系。在计算机科学中,图被广泛应用于网络结构、社交关系、分子结构等领域。随着深度学习的发展,图神经网络(GNNs)成为处理图结构数据的强大工具,推动了图论在人工智能中的应用。因此,深入理解图论的基础图结构及算法,对于掌握图神经网络的原理和应用至关重要。

2. 基础图结构

2.1 图的定义

是由一组顶点(Vertices)和一组连接顶点的边(Edges)组成的数学结构。形式化地,

,图可以表示为 \( G = (V, E) \),其中:

  • V是顶点的集合。
  • E 是边的集合,每条边连接两个顶点。

2.2 图的分类

根据边的性质和图的特性,图可以分为以下几类:

  1. 有向图(Directed Graph)无向图(Undirected Graph)

    • 有向图:每条边有方向,即一条边由一个起点指向一个终点,表示“从起点到终点”的关系。
    • 无向图:每条边没有方向,表示两个顶点之间的双向关系。
  2. 加权图(Weighted Graph)非加权图(Unweighted Graph)

    • 加权图:边上有权重(权值),表示边的强度、距离或成本。
    • 非加权图:边上没有权重。
  3. 简单图(Simple Graph)多重图(Multigraph)

    • 简单图:任意两个顶点之间最多有一条边,且没有自环(边连接同一顶点)。
    • 多重图:允许两个顶点之间有多条边,允许自环。
  4. 完全图(Complete Graph)

    • 每对不同的顶点之间都有一条边。
  5. 连通图(Connected Graph)非连通图(Disconnected Graph)

    • 连通图:任意两个顶点之间至少存在一条路径。
    • 非连通图:存在至少一对顶点之间没有路径。
  6. 树(Tree)森林(Forest)

    • :一种连通的无环图。
    • 森林:由多个不连通的树组成的图。

2.3 图的表示方法

在计算机中,图通常有以下几种常见的表示方法:

  1. 邻接矩阵(Adjacency Matrix)

    • 使用一个二维矩阵A表示图,其中A[i][j]表示顶点 i和顶点 j 之间是否存在边。
    • 有向图A[i][j]=1 表示从 i到 j有边。
    • 无向图:邻接矩阵是对称的,即 A[i][j]=A[j][i]
    • 加权图A[i][j]存储边的权重。
  2. 邻接表(Adjacency List)

    • 对于每个顶点,存储与之相邻的所有顶点列表。
    • 在存储空间上通常比邻接矩阵更高效,特别是对于稀疏图。
  3. 边列表(Edge List)

    • 存储所有边的列表,每条边表示为一对顶点(有向图中为有序对)。

2.4 特殊类型的图

  1. 二分图(Bipartite Graph)

    • 图的顶点可以分为两个不相交的集合,且每条边都连接来自不同集合的顶点。
  2. 树(Tree)和森林(Forest)

    • :一种连通、无环的无向图。
    • 森林:由多个不连通的树组成的图。
  3. 环图(Cycle Graph)

    • 每个顶点的度数为2,形成一个闭合环。
  4. 有向无环图(DAG, Directed Acyclic Graph)

    • 有向图且不包含任何有向环。

3. 基本图算法

图论中有许多经典算法,用于解决各种图相关的问题。以下将介绍几种常见的图算法及其应用。

3.1 图遍历算法

图遍历算法用于访问图中的所有顶点和边,主要包括深度优先搜索(DFS)和广度优先搜索(BFS)。

3.1.1 深度优先搜索(DFS)

深度优先搜索(Depth-First Search, DFS) 是一种通过尽可能深入每个分支来遍历或搜索图的算法。它使用栈(递归实现)来记住下一步要访问的顶点。

算法步骤

  1. 从起始顶点开始,访问该顶点并标记为已访问。
  2. 对每一个未被访问的邻接顶点,递归进行DFS。
  3. 回溯至上一个顶点,继续访问其他未访问的邻接顶点。

应用

  • 检测图中的连通性。
  • 寻找图中的路径。
  • 拓扑排序。

示例代码(Python)

def dfs(graph, start, visited=None):
    if visited is None:
        visited = set()
    visited.add(start)
    print(start)  # 访问节点
    for neighbor in graph[start]:
        if neighbor not in visited:
            dfs(graph, neighbor, visited)
    return visited

# 示例图(邻接表表示)
graph = {
    'A': ['B', 'C'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E']
}

dfs(graph, 'A')

输出:

A
B
D
E
F
C
3.1.2 广度优先搜索(BFS)

广度优先搜索(Breadth-First Search, BFS) 是一种逐层遍历图的算法,使用队列来记住下一步要访问的顶点。

算法步骤

  1. 从起始顶点开始,访问该顶点并标记为已访问。
  2. 将所有未被访问的邻接顶点加入队列。
  3. 从队列中取出一个顶点,重复步骤2,直到队列为空。

应用

  • 计算无权图中的最短路径。
  • 检测图的连通性。
  • 层次遍历。

示例代码(Python)

from collections import deque

def bfs(graph, start):
    visited = set()
    queue = deque([start])
    visited.add(start)
    
    while queue:
        vertex = queue.popleft()
        print(vertex)  # 访问节点
        for neighbor in graph[vertex]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)

# 示例图(邻接表表示)
graph = {
    'A': ['B', 'C'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E']
}

bfs(graph, 'A')

输出:

A
B
C
D
E
F

3.2 最短路径算法

最短路径算法用于在图中找到两个顶点之间的最短路径。常见的算法包括Dijkstra算法、Bellman-Ford算法和Floyd-Warshall算法。

3.2.1 Dijkstra算法

Dijkstra算法 是一种用于计算单源最短路径的贪心算法,适用于加权图,且要求所有边的权重为非负。

算法步骤

  1. 初始化起点到所有顶点的距离为无穷大,起点到自身的距离为0。
  2. 将所有顶点加入未访问集合。
  3. 从未访问集合中选择距离起点最近的顶点,标记为已访问。
  4. 更新该顶点邻接顶点的距离,如果通过该顶点能缩短距离,则更新距离。
  5. 重复步骤3和4,直到所有顶点被访问。

应用

  • GPS导航系统。
  • 网络路由算法。

示例代码(Python)

import heapq

def dijkstra(graph, start):
    heap = []
    heapq.heappush(heap, (0, start))
    distances = {vertex: float('inf') for vertex in graph}
    distances[start] = 0
    visited = set()
    
    while heap:
        current_distance, current_vertex = heapq.heappop(heap)
        
        if current_vertex in visited:
            continue
        visited.add(current_vertex)
        
        for neighbor, weight in graph[current_vertex].items():
            distance = current_distance + weight
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(heap, (distance, neighbor))
    
    return distances

# 示例图(邻接表表示,带权重)
graph = {
    'A': {'B': 1, 'C': 4},
    'B': {'A': 1, 'D': 2, 'E': 5},
    'C': {'A': 4, 'F': 3},
    'D': {'B': 2},
    'E': {'B': 5, 'F': 1},
    'F': {'C': 3, 'E': 1}
}

distances = dijkstra(graph, 'A')
print(distances)

输出:

{'A': 0, 'B': 1, 'C': 4, 'D': 3, 'E': 6, 'F': 5}
3.2.2 Bellman-Ford算法

Bellman-Ford算法 是另一种用于计算单源最短路径的算法,适用于含有负权边的图。它可以检测图中是否存在负权环。

算法步骤

  1. 初始化起点到所有顶点的距离为无穷大,起点到自身的距离为0。
  2. 对所有边进行V-1次松弛操作(V为顶点数量)。
  3. 检查是否存在可以进一步松弛的边,若存在则说明图中存在负权环。

应用

  • 适用于包含负权边的网络分析。
  • 经济学中的最优投资路径分析。
3.2.3 Floyd-Warshall算法

Floyd-Warshall算法 是一种用于计算所有顶点对之间最短路径的动态规划算法,适用于有向或无向图。

算法步骤

  1. 初始化一个距离矩阵,记录所有顶点对之间的边权。
  2. 逐步考虑每个顶点作为中间点,更新顶点对之间的最短路径。
  3. 最终得到所有顶点对之间的最短路径长度。

应用

  • 计算密集型图中的所有最短路径。
  • 网络流量分析。

3.3 最小生成树算法

最小生成树(Minimum Spanning Tree, MST)是指在连通加权图中,选取一棵生成树,使得所有边权之和最小。

3.3.1 Kruskal算法

Kruskal算法 是一种基于边的贪心算法,用于生成最小生成树。它按照边权从小到大排序,逐条选取不形成环的边。

算法步骤

  1. 将所有边按权重从小到大排序。
  2. 初始化一个森林,每个顶点都是一个独立的树。
  3. 依次选择权重最小的边,如果该边连接的两个顶点属于不同的树,则将它们合并。
  4. 重复步骤3,直到所有顶点在一棵树中。

应用

  • 网络设计(如电网、通信网络)。
  • 图聚类。
3.3.2 Prim算法

Prim算法 是另一种基于顶点的贪心算法,用于生成最小生成树。它从一个起始顶点开始,逐步扩展最小权重的边。

算法步骤

  1. 初始化起始顶点,将其加入生成树。
  2. 寻找连接生成树和未加入生成树的最小权重的边。
  3. 将该边和新的顶点加入生成树。
  4. 重复步骤2和3,直到所有顶点都在生成树中。

应用

  • 类似于Kruskal算法,用于网络设计和优化。

3.4 拓扑排序

拓扑排序(Topological Sorting) 是一种对有向无环图(DAG)进行线性排序的方法,使得对于每条有向边 \( u \rightarrow v \),顶点 \( u \) 都排在顶点 \( v \) 的前面。

算法步骤(Kahn算法):

  1. 计算所有顶点的入度。
  2. 将所有入度为0的顶点加入队列。
  3. 从队列中取出一个顶点,加入拓扑序列,并减少其邻接顶点的入度。
  4. 重复步骤3,直到队列为空。
  5. 若拓扑序列中包含所有顶点,则排序成功;否则,图中存在环。

应用

  • 任务调度。
  • 编译器中的代码优化。

3.5 强连通分量

强连通分量(Strongly Connected Components, SCCs) 是指在有向图中,每个顶点都可以通过有向路径到达其他所有顶点的极大子集。

算法步骤(Kosaraju算法):

  1. 对图进行DFS,记录顶点的完成时间顺序。
  2. 反转图中的所有边。
  3. 按完成时间的逆序对反转图进行DFS,标记强连通分量。

应用

  • 化简有向图。
  • 语义分析和代码优化。

4. 图论在图神经网络中的应用

4.1 图神经网络概述

图神经网络(Graph Neural Networks, GNNs)是针对图结构数据设计的一类神经网络模型。传统的神经网络(如卷积神经网络)主要处理欧几里得数据(如图像),而GNN能够有效处理非欧几里得数据,通过学习节点、边及图整体的表示,从而用于分类、回归、生成等任务。

GNNs的核心思想是通过信息传递机制,聚合邻居节点的信息,更新节点的表示。常见的GNN模型包括图卷积网络(Graph Convolutional Networks, GCNs)、图注意力网络(Graph Attention Networks, GATs)等。

4.2 图卷积网络(GCN)

图卷积网络(GCN) 是最早被广泛研究和应用的GNN模型之一。GCN通过在图的结构上定义卷积操作,能够捕捉节点之间的局部关系。

基本原理

  • 节点的表示通过与其邻居节点的特征进行聚合得到。
  • 使用归一化的邻接矩阵进行特征加权,避免特征爆炸或消失。
  • 可以堆叠多层GCN,以捕捉更远的邻居信息。

数学表示

\[
H^{(l+1)} = \sigma\left(\hat{D}^{-1/2} \hat{A} \hat{D}^{-1/2} H^{(l)} W^{(l)}\right)
\]
其中:
 \( \hat{A} = A + I \) 是加上自环的邻接矩阵。
 \( \hat{D} \) 是 \( \hat{A} \) 的度矩阵。
 \( H^{(l)} \) 是第 \( l \) 层的节点特征。
 \( W^{(l)} \) 是第 \( l \) 层的权重矩阵。
 \( \sigma \) 是激活函数(如ReLU)。

4.3 图注意力网络(GAT)

图注意力网络(GAT) 引入了注意力机制,使得每个节点在聚合邻居信息时能够分配不同的权重,以适应不同邻居的重要性。

基本原理

  • 为每个邻居节点计算一个注意力系数,表示其对当前节点的重要性。
  • 使用这些注意力系数对邻居节点的特征进行加权求和。
  • 通过多头注意力机制进一步增强模型的表达能力。

数学表示

\[
e_{ij} = \text{LeakyReLU}\left(a^T [W h_i || W h_j]\right)
\]
\[
\alpha_{ij} = \frac{\exp(e_{ij})}{\sum_{k \in \mathcal{N}(i)} \exp(e_{ik})}
\]
\[
h_i' = \sigma\left(\sum_{j \in \mathcal{N}(i)} \alpha_{ij} W h_j\right)
\]
其中:
 \( a \) 是注意力权重向量。
\( W \) 是特征变换矩阵。
 \( || \) 表示连接操作。
 \( \mathcal{N}(i) \) 是节点 \( i \) 的邻居集合。

4.4 应用案例

  1. 社交网络分析

    • 节点分类:识别用户的兴趣类别。
    • 链接预测:预测潜在的社交连接。
  2. 推荐系统

    • 基于用户和物品的图结构,推荐相关物品。
  3. 分子和化学分析

    • 分子属性预测:预测分子的物理化学性质。
    • 药物发现:发现潜在的药物分子结构。
  4. 交通网络优化

    • 路径规划和拥堵预测。

5. 示例代码

本文将通过Python的NetworkX库构建图,并实现基本的图算法和一个简单的图神经网络模型。

5.1 使用NetworkX进行图的构建与算法实现

安装NetworkX

pip install networkx

构建图并实现DFS和BFS

import networkx as nx
from collections import deque

# 构建一个无向图
G = nx.Graph()

# 添加节点
G.add_nodes_from(['A', 'B', 'C', 'D', 'E', 'F'])

# 添加边
G.add_edges_from([
    ('A', 'B'),
    ('A', 'C'),
    ('B', 'D'),
    ('B', 'E'),
    ('C', 'F'),
    ('E', 'F')
])

# 深度优先遍历
def dfs_networkx(graph, start):
    visited = set()
    stack = [start]
    
    while stack:
        vertex = stack.pop()
        if vertex not in visited:
            print(vertex)
            visited.add(vertex)
            # 添加未访问的邻居到栈
            stack.extend(reversed(list(graph.neighbors(vertex))))
    return visited

print("DFS Traversal:")
dfs_networkx(G, 'A')

# 广度优先遍历
def bfs_networkx(graph, start):
    visited = set()
    queue = deque([start])
    visited.add(start)
    
    while queue:
        vertex = queue.popleft()
        print(vertex)
        for neighbor in graph.neighbors(vertex):
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)
    return visited

print("\nBFS Traversal:")
bfs_networkx(G, 'A')

输出:

DFS Traversal:
A
B
D
E
F
C

BFS Traversal:
A
B
C
D
E
F

Dijkstra算法实现

# 构建一个有向加权图
G_weighted = nx.DiGraph()

# 添加边及其权重
G_weighted.add_weighted_edges_from([
    ('A', 'B', 1),
    ('A', 'C', 4),
    ('B', 'D', 2),
    ('B', 'E', 5),
    ('C', 'F', 3),
    ('E', 'F', 1)
])

# 使用NetworkX内置的Dijkstra算法计算最短路径
shortest_paths = nx.single_source_dijkstra_path_length(G_weighted, 'A')
print("\nDijkstra Shortest Paths from A:")
for node, distance in shortest_paths.items():
    print(f"Distance from A to {node}: {distance}")

输出:

Dijkstra Shortest Paths from A:
Distance from A to A: 0
Distance from A to B: 1
Distance from A to D: 3
Distance from A to E: 6
Distance from A to C: 4
Distance from A to F: 5

5.2 简单图神经网络的实现

本文使用PyTorch Geometric库实现一个简单的图卷积网络(GCN)进行节点分类任务。

安装PyTorch Geometric

请根据操作系统和PyTorch版本,参考PyTorch Geometric官方安装指南。

示例代码:使用GCN进行节点分类

import torch
import torch.nn.functional as F
from torch_geometric.datasets import Planetoid
import torch_geometric.transforms as T
from torch_geometric.nn import GCNConv

# 加载Cora数据集
dataset = Planetoid(root='/tmp/Cora', name='Cora', transform=T.NormalizeFeatures())

class GCN(torch.nn.Module):
    def __init__(self):
        super(GCN, self).__init__()
        self.conv1 = GCNConv(dataset.num_node_features, 16)  # 第一层GCN,输出维度为16
        self.conv2 = GCNConv(16, dataset.num_classes)         # 第二层GCN,输出维度为类别数

    def forward(self, data):
        x, edge_index = data.x, data.edge_index
        x = self.conv1(x, edge_index)  # GCN第一层
        x = F.relu(x)                  # 激活函数
        x = F.dropout(x, training=self.training)  # Dropout层
        x = self.conv2(x, edge_index)  # GCN第二层
        return F.log_softmax(x, dim=1)  # Log-Softmax

# 初始化模型、优化器和损失函数
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = GCN().to(device)
data = dataset[0].to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
criterion = torch.nn.NLLLoss()

# 训练函数
def train():
    model.train()
    optimizer.zero_grad()
    out = model(data)
    loss = criterion(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()
    return loss.item()

# 测试函数
def test():
    model.eval()
    out = model(data)
    pred = out.argmax(dim=1)
    accs = []
    for mask in [data.train_mask, data.val_mask, data.test_mask]:
        correct = pred[mask] == data.y[mask]
        acc = int(correct.sum()) / int(mask.sum())
        accs.append(acc)
    return accs

# 训练模型
for epoch in range(200):
    loss = train()
    train_acc, val_acc, test_acc = test()
    if epoch % 20 == 0:
        print(f'Epoch: {epoch:03d}, Loss: {loss:.4f}, Train Acc: {train_acc:.4f}, Val Acc: {val_acc:.4f}, Test Acc: {test_acc:.4f}')

# 最终测试准确率
print(f'\nFinal Test Accuracy: {test_acc:.4f}')

输出(部分):

Epoch: 000, Loss: 2.0794, Train Acc: 0.2071, Val Acc: 0.2100, Test Acc: 0.2000
...
Epoch: 180, Loss: 0.1462, Train Acc: 0.8393, Val Acc: 0.8025, Test Acc: 0.8060
Epoch: 200, Loss: 0.1294, Train Acc: 0.8545, Val Acc: 0.8075, Test Acc: 0.8060

Final Test Accuracy: 0.8060

代码说明

  1. 数据加载

    • 使用Cora数据集,该数据集包含科学论文的引用网络,每个节点代表一篇论文,边代表引用关系,节点特征为词袋向量,标签为论文类别。
    • NormalizeFeatures 对节点特征进行归一化处理。
  2. 模型构建

    • 两层GCN,每层包括一个GCN卷积层、ReLU激活、Dropout。
    • 最后一层使用Log-Softmax进行多分类。
  3. 训练与测试

    • 使用交叉熵损失函数(NLLLoss)。
    • 使用Adam优化器。
    • 每20个epoch输出一次训练、验证和测试准确率。

5.3 完整代码仓库

为了便于读者实践,完整的示例代码可以在GitHub仓库中找到。

6. 总结与展望

本文系统地介绍了图论的基础图结构、常用算法及其在图神经网络中的应用。图论作为理解和构建图结构数据的重要工具,其算法不仅在计算机科学的多个领域中发挥着关键作用,也为图神经网络的发展提供了坚实的理论基础。随着GNNs在社交网络分析、推荐系统、分子建模等领域的广泛应用,图论和GNNs的结合将推动更多创新性的成果产生。

未来,随着图数据规模的不断扩大和复杂性的增加,研究高效的图算法和更强大的GNN模型将成为重要的研究方向。此外,将图论与其他数学分支(如代数、拓扑)相结合,探索更深层次的图结构特性,也将为图神经网络的性能提升和应用范围扩展提供新的契机。

7. 参考资料

  1. 《图论及其应用》(Reinhard Diestel 著)
  2. 《图神经网络》(Zhiyuan Zhang, Maarten de Rijke 著)
  3. NetworkX官方文档:Software for Complex Networks — NetworkX 3.4.2 documentation
  4. PyTorch Geometric官方文档:https://pytorch-geometric.readthedocs.io/en/latest/
  5. 《深度学习》(Ian Goodfellow, Yoshua Bengio, Aaron Courville 著)
  6. GCN论文:Thomas Kipf, Max Welling. “Semi-Supervised Classification with Graph Convolutional Networks.” ICLR 2017.
  7. GAT论文:Petar Veličković et al. “Graph Attention Networks.” ICLR 2018.

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

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

相关文章

【docker】docker desktop 在windows上支持 host模式

针对以前的情况&#xff0c;对于 Windows 和 macOS 用户&#xff0c;是不能够使用host模式的。只能在linux上才能够使用 更新日志 docker desktop 在4.34.0版本&#xff0c;开始支持host模式。

【ALGC】探秘 ALGC—— 卓越数据处理能力的科技瑰宝

我的个人主页 我的领域&#xff1a;人工智能篇&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;&#x1f44d;点赞 收藏❤ 在大数据时代&#xff0c;如何高效地处理和分析海量数据是一个核心挑战。ALGC&#xff08;Advanced Learning and Generalized Comp…

FPGA实现MIPI转FPD-Link车载同轴视频传输方案,基于IMX327+FPD953架构,提供工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐本博主所有FPGA工程项目-->汇总目录我这里已有的 MIPI 编解码方案 3、本 MIPI CSI-RX IP 介绍4、详细设计方案设计原理框图IMX327 及其配置FPD-Link视频串化-解串方案MIPI CSI RX图像 ISP 处理图像缓存HDMI输出工程源码架构 5、…

STM32 与 AS608 指纹模块的调试与应用

前言 在嵌入式系统中&#xff0c;指纹识别作为一种生物识别技术&#xff0c;广泛应用于门禁系统、考勤机、智能锁等场景。本文将分享如何在 STM32F103C8T6 开发板上使用 AS608 指纹模块&#xff0c;实现指纹的录入和识别功能。 硬件准备 STM32F103C8T6 开发板AS608 指纹模块…

Linux Shell 基础教程⑧

Shell 教程 Shell 是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。 Shell 是指一种应用程序&#xff0c;这个应用程序提供了一个界面&#xff0c;用户通过这个界面访问操作系统内核的服务。 Ke…

网络刷卡器的功能和使用场景

网络刷卡器是一种连接互联网的设备&#xff0c;能够通过网络将读取到的各种卡片信息传输至服务器进行处理。这类刷卡器通常支持多种类型的卡片&#xff0c;如银行卡、身份证、会员卡、公交卡等&#xff0c;并运用现代信息技术确保数据的安全性和高效性&#xff0c;功能十分强大…

Centos7下的根口令重置与GRUB修复

目录 1. 利用GRUB进入单用户模式重置根口令&#xff1b; 步骤较多方法 步骤较少方法&#xff1a;这里主要是把重新以rw方式挂载的步骤换为了在编辑模式直接修改 2. 利用Linux系统安装光盘进入急救模式重置根口令&#xff1b; 3. 如果GRUB损坏&#xff0c;利用Linu…

赋能新一代工业机器人-望获实时linux在工业机器人领域应用案例

在工业4.0蓬勃发展的当下&#xff0c;工业机器人作为制造业转型升级的中流砥柱&#xff0c;正朝着超精密、极速响应的方向全力冲刺。然而&#xff0c;为其适配理想的望获实时Linux系统&#xff0c;却犹如寻找开启宝藏之门的关键钥匙&#xff0c;成为众多企业在智能化进程中的棘…

“无需代码,一句需求,立刻看到你的创意变成网页”==>前端AI工具 “V0”

想象一下&#xff0c;一个能帮你跳过所有烦人的代码编写过程&#xff0c;直接根据你的需求生成页面的 AI&#xff01;没错&#xff0c;这就是 v0&#xff01;你只需要用自然语言描述你想要的界面&#xff0c;v0 就会挥一挥它的“魔法鼠标”&#xff0c;立刻生成漂亮的 UI 代码。…

C语言(一)——初识C语言

目录 简单认识一段代码 数据类型 变量和常量 变量的作用域和变量的生命周期 常量 字符串 转义字符 注释 函数 数组 操作符 关键字 结构体 结构的声明 结构成员的类型 结构体变量的初始化 结构体传参 简单认识一段代码 main()函数是程序的入口&#xff0c;所以…

频繁拿下定点,华玉高性能中间件迈入商业化新阶段

伴随着智能驾驶渗透率的快速增长&#xff0c;中国基础软件市场开始进入黄金窗口期。 近日&#xff0c;华玉通软&#xff08;下称“华玉”&#xff09;正式获得某国内头部轨道交通产业集团的智能化中间件平台定点项目。这将是华玉在基础软件领域深耕和商业化发展过程中的又一重…

怎么学习数据结构与算法?

数据结构与算法 提及数据结构与算法&#xff0c;许多人可能会不自觉地皱起眉头。似乎在不知不觉中&#xff0c;以字节跳动为代表的一批公司&#xff0c;在面试环节开始了一场针对算法的连环盘问。若非事先系统地刷过一系列算法题目&#xff0c;想要轻松通过这一关&#xff0c;…

MySQL通过日志恢复数据的步骤

试验环境&#xff1a;Windows Server2012 r2、MySql-8.0.27-winx64。 1、先检查MySQL有没有开启binlog日志 通过下面的SQL命令查看MySQL是否开启日志以及日志文件的位置&#xff1a; show variables like %log_bin% 执行结果如下图所示&#xff1a; 图中&#xff0c;log_bi…

react+antd的Table组件编辑单元格

需求&#xff1a;新增加一行&#xff0c;且单元格可以编辑 场景&#xff1a;真实的业务需求&#xff08;antd 3 版本react&#xff09; 效果图&#xff1a;1. 默认增加一行时&#xff0c;第一列是下拉选择框&#xff0c;第2 3列是TextArea&#xff0c;图1 2. 当下拉选择的数据不…

基于Springboot的数码产品抢购系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实…

LabVIEW电机控制中的主动消抖

在LabVIEW电机控制系统中&#xff0c;抖动现象&#xff08;如控制信号波动或机械振动&#xff09;会影响系统的稳定性和精度。通过使用主动消抖算法&#xff0c;可以有效降低抖动&#xff0c;提高控制性能。本文将介绍几种主流的主动消抖算法&#xff0c;并结合具体应用案例进行…

连续自成核退火热分级(SSA)技术表征共聚聚丙烯(PP)分子链结构

共聚聚丙烯是一种多相多组分高分子体系&#xff0c;体系中同时存在多种链组成、序列结构和相结构。研究表明&#xff0c;共聚聚丙烯中除了均聚聚丙烯外&#xff0c;还有乙丙无规共聚物&#xff08;又称乙丙橡胶&#xff0c;EPR&#xff09;及不同序列长度的乙丙嵌段共聚物&…

游戏AI实现-寻路算法(Dijkstra)

戴克斯特拉算法&#xff08;英语&#xff1a;Dijkstras algorithm&#xff09;&#xff0c;又称迪杰斯特拉算法、Dijkstra算法&#xff0c;是由荷兰计算机科学家艾兹赫尔戴克斯特拉在1956年发现的算法。 算法过程&#xff1a; 1.首先设置开始节点的成本值为0&#xff0c;并将…

C# OpenCV机器视觉:缺陷检测

在一个阳光明媚的早晨&#xff0c;阿强正准备享受他的一杯咖啡&#xff0c;突然接到了老板的电话。“阿强&#xff0c;我们的生产线出现了问题&#xff01;有几个产品的质量不合格&#xff0c;客户投诉不断&#xff01;你能不能想办法解决这个问题&#xff1f;” 阿强一听&…

模型 ADDIE(分析、设计、开发、实施、评估)

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。分析、设计、开发、实施、评估教学法。 1 模型ADDIE(分析、设计、开发、实施、评估)的应用 1.1 个人IP私域运营体系构建 在个人IP私域运营领域&#xff0c;ADDIE模型被应用于构建一个系统的运营体系…