【Graph】NetworkX官方基础教程

news2024/9/20 1:31:33

NetworkX官方基础教程

  • 图的基础知识
    • 1.1 图(graph)及其分类
    • 1.2 节点的度(degree)
    • 1.3 子图(subgraph)
    • 1.4 连通图
    • 1.5 图的矩阵表示
  • NetworkX概述
  • NetworkX基础教程
    • 1. 创建图
    • 2. 节点
    • 3. 边
    • 4. 清空图
    • 5. 图可视化
    • 6. 访问图的元素属性
    • 7. 向图、节点或边种添加属性
    • 8. 有向图
    • 9. 画出复杂网络
    • 10.图结构持久化和从外部文件读取图数据
    • 11. 多图
  • 参考资料

本文作为对图结构和复杂网络的快速上手,内容包括图基础知识,NetworkX使用,一个NetworkX构建实体关系和可视化的案例

图的基础知识

1.1 图(graph)及其分类

(1) 图的定义:图是由点集 V = v i V={v_i} V=vi以及V中元素无序对的集合 E = e k E={e_k} E=ek所构成的二元组,记为 G = ( V , E ) G=(V,E) G=(V,E),V中的元素 v i v_i vi称为节点,E中的元素 e k e_k ek称为边。通俗理解:图是节点和边构成及集合
(2) 简单图:不含环和多重边的图称为简单图;多重图:含有多重边的图
(3) 完全图:每一对节点之间都有边相连的简单图称为完全图;有向完全图: 每一对节点间有且仅有一条有向边的简单图
(4) 二部图:图 G ( V , E ) G(V,E) G(V,E)的点集V可以分成两个非空子集X,Y,即X并Y等于V,X交Y等于空集,如果E中的每条边的两个端点必有一个属于X,另一端点属于Y,则成G为二部图,有时记为: G = ( X , Y , E ) G = (X,Y,E) G=(X,Y,E)
二部图

1.2 节点的度(degree)

(1) 节点的度的定义:与节点(node)V相连的边(edge)数之和称为节点的度,记为deg(v),简记为:d(v)
(2) 悬挂点:度为1的节点称为悬挂点;悬挂边:连接悬挂点的边称为悬挂边
(3) 任何图中,节点的度之和等于边数的2倍,次数为奇数的节点必为偶数个。
(4) 出度:在有向图中,以节点 v i v_i vi为起始点的边数称为出度;入度:在有向图中,以节点 v i v_i vi为终止点的边数称为入度

1.3 子图(subgraph)

(1)图G=(E,V),若E’是E的子集,V’是V的子集,且E’中的边仅与V’中的节点相关联,则称 G ’ = ( V ’ , E ’ ) G’=(V’,E’) G=(V,E)是G的一个子图。

1.4 连通图

(1)各边相异的道路称为迹(trace),也成为简单路径(simple path);各节点相异的道路称为(track),也称为基本路径(essential path);起点和终点重合的道路称为回路(circuit),否则称为开路(open circuit)。
(2)连通图:图中任意两点间至少有一条道路相连,则称该图为连通图。

1.5 图的矩阵表示

赋权图 G = ( E , V ) G=(E,V) G=(E,V),其边 ( v i , v j ) (v_i,v_j) (vivj)有权 w i j w_{ij} wij,构造矩阵 A = ( a i j ) A=(a_{ij}) A=(aij),则称矩阵A为赋权图G的邻接矩阵。

NetworkX概述

NetworkX是一个Python包,用于创建、操作和研究复杂网络的结构、动力学和功能。使用NetworkX,可以以标准和非标准数据格式加载和存储网络,生成多种类型的随机和经典网络,分析网络结构,构建网络模型,设计新的网络算法,绘制网络,等等

networkx包安装

$ pip install networkx

NetworkX基础教程

主要包括创建图,节点,边,访问图元素,添加图属性,清空图,图可视化,图持久化,从外部文件读取图数据等

1. 创建图

首先创建一个空图,这个空图没有任何节点和边,且这个空图是一个无向图nx.Graph:

import networkx as nx
G = nx.Graph()

根据定义,图是节点(顶点)以及已识别的节点对(称为边,链接等)的集合。在 NetworkX 中,节点可以是任何可哈希(hashable)对象,例如,文本字符串、图像、XML对象、另一个图、自定义节点对象等。

python 中的None不能作为节点。

2. 节点

图可以以多种形式扩张。NetworkX包括许多图生成函数和工具,用于读取和写入多种格式的图。
作为简单开始,可以使用add_node每次添加一个节点:

G.add_node(1)

或者从可迭代容器(iterable)(如列表)中添加多个节点:

G.add_nodes_from([2, 3])
G.add_nodes_from("spam")  # 字符串可迭代对象,实际增加的是4个节点: 's', 'p', 'a', 'm'

也可以在添加节点的时候增加节点的属性,但是有格式要求,在add_nodes_from中将每个节点元素设置为元组格式并且,元组内指定属性为字典结构(node, node_attribute_dict)

G.add_nodes_from([
    (4, {"color": "red"}),
    (5, {"color": "green"}),
])

一个图中的节点可以合并到另一个图,同样是使用add_nodes_from

H = nx.path_graph(10)  # path_graph是生成一个由n-1条边线性连接的n个节点的路径图
G.add_nodes_from(H)

现在图G中节点包括原H中的节点。相反,也可以将整个图H作为图G中的一个节点:

G.add_node(H)

现在图G 将图H作为其中一个节点。这种灵活性非常强大,因为它允许图形组成的图形,文件组成的图形,函数组成的图形等等。值得考虑如何构建应用程序,以便节点是有用的实体。当然,如果您愿意,您始终可以在G中使用唯一标识符,并按标识符键记节点信息的单独字典。

如果哈希取决于其内容,则不应更改节点对象。

在创建完节点后就可以查看节点信息:

G.number_of_nodes()  # 5
G.nodes()  # NodeView((1, 2, 3, 4, 5))

和增加一样,也可以移除节点:

G.remove_node(1)
G.remove_nodes_from([2, 3])

3. 边

图也可以通过一次性增加一条边进行生长,使用add_edge

G.add_edge(1, 2)
e = (2, 3)
G.add_edge(*e)  # 采用元组解包方式

也可以添加多个边,使用add_edges_from

G.add_edges_from([(1, 2), (1, 3)])

或者通过添加任何边的ebunchebunch是边的元组的任何可迭代容器。边的元组可以是 2 元组节点,也可以是 3 元组:在 2 个节点后跟边的属性字典,如(2, 3,{'weight':3.1415})

G.add_edges_from([(2, 4, {'weight': 3})])

还有一个方法是add_weighted_edges_from,这个可以指定三元组,第三个元素是边权重:

G = nx.Graph()
G .add_weighted_edges_from([(1, 2, 0.125), (1, 3, 0.75), (2, 4, 1.2), (3, 4, 0.375)])
G[1][2]  # {'weight': 0.125}

边创建好之后,可以查看图的表情况:

G.number_of_edges()  # 4
G.edges()  # EdgeView([(1, 2), (1, 3), (2, 3), (2, 4)])

同样也可以移除边:

G.remove_edge(1, 2)
G.remove_edges_from([(1, 3), (2, 4)])

最后边可以直接在空图中或者还没有建立节点之前创建,如果指定的边的节点不存在图对象中,会先创建出节点:

G = nx.Graph()
G.add_edge(1, 2)
G.nodes  # NodeView((1, 2)),没有提前创建节点,但是直接创建边依旧有节点

添加新的节点/边时,NetworkX 悄悄地忽略任何已经存在的。

G.add_edges_from([(1, 2), (1, 3)])
G.add_node(1)
G.add_edge(1, 2)
G.add_node("spam")        # adds node "spam"
G.add_nodes_from("spam")  # adds 4 nodes: 's', 'p', 'a', 'm'
G.add_edge(3, 'm')

此时,图G 包含 8 个节点和 3 条边:

>>> G.number_of_nodes()
8
>>> G.number_of_edges()
3

邻接报告(adjacency reporting)的顺序(例如,G.adj、G.successors、G.predecessors)是边添加的顺序。 然而,G.edges 的顺序是邻接的顺序,包括节点的顺序和每个节点的邻接。 请参见下面的示例:

DG = nx.DiGraph()
DG.add_edge(2, 1)   # adds the nodes in order 2, 1
DG.add_edge(1, 3)
DG.add_edge(2, 4)
DG.add_edge(1, 2)
assert list(DG.successors(2)) == [1, 4]
assert list(DG.edges) == [(2, 1), (2, 4), (1, 3), (1, 2)]

4. 清空图

使用clear方法清空图

G.clear()

此时在查看图的节点和边属性

G.number_of_nodes()  # 0
G.nodes()  # NodeView(())
G.number_of_edges()  # 0
G.edges()  # EdgeView([])

5. 图可视化

nx.draw_networkx(G)
import matplotlib.pyplot as plt
plt.show()

图可视化

6. 访问图的元素属性

主要是集中在G.nodes, G.edges, G.adj and G.degree四个属性方法,分别查看图的节点,边,邻居(邻接),度的信息,我们来看一下他们的输出结构:

list(G.nodes)  #  [1, 2, 3, 4, 5],原始输出是NodeView类型
list(G.edges)  # [(1, 2), (1, 3), (2, 3), (2, 4)],原始输出是EdgeView类型
list(G.adj[1])  # or list(G.neighbors(1))  [2, 3]
G.degree[1]  # the number of edges incident to 1 # 2

如果节点带有属性,想单独访问一个节点的属性,可以在G.nodes后面接节点的下标:

G = nx.Graph()
G.add_node(1, name='gp')
G.add_node(2)
G.nodes[1]  # {'name': 'gp'}

可以指定查询一个或者多个节点的涉及的边:

G.edges([1, 2])  # 所有存在的节点输出边
Out[66]: EdgeDataView([(1, 2), (1, 3), (2, 3), (2, 4)])
G.edges(1)
Out[67]: EdgeDataView([(1, 2), (1, 3)])

另一种访问边的方法是直接对G对象使用下标访问,比如:

G[1]  # 等价于G.adj[1]
Out[75]: AtlasView({2: {}, 3: {}})

如果指定了两个节点,要访问两节点构成的边的属性信息,可以在G.edges中使用直接使用下标属性:

G.edges[2, 4]
Out[87]: {'weight': 3}

等同于直接对G对象做两次节点作为下标的访问:

G[2][4]
Out[91]: {'weight': 3}

同理在构建边的时候,也可以只用这种方式在创建好之后在设置边的属性:

G = nx.Graph()
G.add_node(1)
G.add_node(2)
G.add_edge(1, 2)
G[1][2]['color'] = 'red'
G[1][2]['weight'] = 3
G[1]  # AtlasView({2: {'color': 'red', 'weight': 3}})

如果要对全部边进行访问,不仅访问边的节点,而且还要访问边的属性,使用G.edges.data()方法,比如:

G = nx.Graph()
G.add_weighted_edges_from([(1, 2, 0.125), (1, 3, 0.75), (2, 4, 1.2), (3, 4, 0.375)])
for (u, v, wt) in G.edges.data():
    print(u, v, wt)
# 1 2 {'weight': 0.125}
# 1 3 {'weight': 0.75}
# 2 4 {'weight': 1.2}
# 3 4 {'weight': 0.375}

G.adj是一个多层嵌套字典的格式,记录每个点的近邻,以及近邻的属性:

G.adj
Out[40]: AdjacencyView({1: {2: {}, 3: {}}, 2: {1: {}, 3: {}, 4: {'weight': 3}}, 3: {2: {}, 1: {}}, 4: {2: {'weight': 3}}, 5: {}})

比如指定节点2的近邻,分别有1,3,4,并且4有属性边权:

G.adj[2]
Out[41]: AtlasView({1: {}, 3: {}, 4: {'weight': 3}})

也可以直接对G对象使用节点下标,作用等同于在找近邻:

G = nx.Graph()
G.add_node(1, name='gp')
G.add_node(2)
G.add_edge(1, 2)
G[2]  # AtlasView({1: {}})
G.adj[2]  # AtlasView({1: {}})

如果仅要输出近邻节点的列表:

list(G.adj[2])  # [1, 3, 4]

可以将AtlasView作为字典循环迭代出来:

for i, j in G.adj.items():
    print(i, j)
# 1 {2: {}, 3: {}}
# 2 {1: {}, 3: {}, 4: {'weight': 3}}
# 3 {2: {}, 1: {}}
# 4 {2: {'weight': 3}}
# 5 {}

查看近邻也可以使用neighbors方法,指定一个节点:

G.neighbors(2)  # <dict_keyiterator at 0x7fb864efb410>
list(G.neighbors(2))  # [1, 3, 4]

最后是查看节点的度,结构依旧是个字典:

G.degree
Out[47]: DegreeView({1: 2, 2: 3, 3: 2, 4: 1, 5: 0})

如果要访问某个节点的度,使用字典的key访问,无向图的度不分出入:

G.degree[2]  # 3

度默认边出现一次权重是1,如果本身手动指定了权重,在degree方法中增加weight=‘weight’,其中weight是自动的权重的key值:

G = nx.Graph()
G.add_weighted_edges_from([(1, 2, 0.25)])
G.degree(1, weight='weight')  # 0.25

或者:

G = nx.Graph()
G.add_edge(1, 2)
G[1][2]['wt'] = 0.25
G.degree(1, weight='wt') 

直接指定节点,获取节点的度:

G.degree[1]
Out[48]: 2

也可以指定多个节点,返回存在节点的度:

G.degree([2, 3])
Out[54]: DegreeView({2: 3, 3: 2})

7. 向图、节点或边种添加属性

可以向图,以及节点和边中添加类似颜色,权重,标签甚至任何Python对象的属性,比如对图对象,可以在创建的时候就指定属性,也可以创建完成之后增加:

G = nx.Graph(name='gp')
G.graph  #  {'name': 'gp'}
G2 = nx.Graph()
G2.graph['name'] = 'gp'
G.graph  # {'name': 'gp'}

同样对于节点node也有对应的API进行属性赋值和增加add_nodeadd_nodes_fromG.nodes

G = nx.Graph()
G.add_node(1)
G.nodes[1]['name'] = 'gp'
G.nodes.data()  # NodeDataView({1: {'name': 'gp'}})

在节点初始化的时候就创建:

G.add_nodes_from([1, 2], name='gp')  # 多个节点相同属性
G.add_node(1, name='gp')  # 单个节点创建属性

同理对于边也是这样操作:

G.add_edge(1, 2, weight=4.7 )
G.add_edges_from([(3, 4), (4, 5)], color='red')
G.add_edges_from([(1, 2, {'color': 'blue'}), (2, 3, {'weight': 8})])
G[1][2]['weight'] = 4.7
G.edges[3, 4]['weight'] = 4.2

8. 有向图

有向图使用nx.DiGraph,在有向图中,degree分为out_degreein_degree,两者的和等于degree,近邻分为前驱predecessors和后继successors:

DG = nx.DiGraph()
DG.add_weighted_edges_from([(1, 2, 0.5), (3, 1, 0.75)])

查看节点1的近邻,发现只有2没有3,说明是从元组的第一个元素向第二个元素:

DG[1]  # AtlasView({2: {'weight': 0.5}})

查看度,出度和入度:

DG.degree(1)  # 2
DG.in_degree(1)  # 1
DG.out_degree(1)  # 1

有向图的neighborssuccessors结果一致,近邻就是后继,不算前驱:

DG = nx.DiGraph()
DG.add_weighted_edges_from([(1, 2, 0.5), (3, 1, 0.75)])
list(DG.neighbors(1))  # [2]
list(DG.successors(1))  # [2]
list(DG.predecessors(1))  # [3]

有向图可以转化为无向图,使用to_undirected,或者将有向图对象传给无向图:

DG = nx.DiGraph()
DG.add_weighted_edges_from([(1, 2, 0.5), (3, 1, 0.75)])
G = DG.to_undirected()
list(G.neighbors(1))  # [2, 3]

或者:

DG = nx.DiGraph()
DG.add_weighted_edges_from([(1, 2, 0.5), (3, 1, 0.75)])
G = nx.Graph(DG)
list(G.neighbors(1))  # [2, 3]

9. 画出复杂网络

NetworkX不是一个图形绘图软件包,而是一个带有Matplotlib的基本绘图软件包,以及一个使用开源Graphviz软件包的接口,画图首先要导入matplotlib,然后draw_networkx G对象,常用画图参数如下:

import matplotlib.pyplot as plt
G = nx.Graph()
G.add_edges_from([(2, 4), (2, 3), (2, 1), (1, 3)])
G.add_node(5)
options = {
    'node_color': 'green',  # 节点颜色
    'node_size': 1200,  # 节点大小
    'width': 1,  # 边粗
    'alpha': 0.7,  # 节点颜色透明度
    'linewidths': 2,  # 节点边缘线粗细
    'edge_color': 'green',  # 边颜色
    'style': 'dashed',  # 边的线型,默认实线,改为虚线
    'font_size': 13,  # 节点上标签的字体大小
    'font_color': 'white'  # 节点上标签字的颜色
}
nx.draw_networkx(G, **options)
plt.show()

输出效果:
图可视化
进一步可以保存图到本地为图片格式文件:

plt.savefig("./path.png")

10.图结构持久化和从外部文件读取图数据

将图结构保存为pickle格式,使用write_gpickle,读取pickle格式图结构使用read_gpickle

G = nx.Graph()
G.add_edges_from([(2, 4), (2, 3), (2, 1), (1, 3)])
G.add_node(5)
nx.write_gpickle(G, "./graph.pkl")

G2 = nx.read_gpickle("./graph.pkl")
G2.nodes  # NodeView((2, 4, 3, 1, 5))

另外也可以存储为txt文件格式,比如edgelistadjlist格式:

G = nx.Graph()
G.add_weighted_edges_from([(2, 4, 3), (2, 3, 2), (2, 1, 1), (1, 3, 5)])
nx.write_edgelist(G, "graph.edgelist")
G2 = nx.read_edgelist("graph.edgelist")
G2.edges.data()  # EdgeDataView([('2', '4', {'weight': 3}), ('2', '3', {'weight': 2}), ('2', '1', {'weight': 1}), ('3', '1', {'weight': 5})])

查看保存的数据,结果是空格分隔符的三元素,第三个元素是属性字典,第一第二是两个互相连接节点:

2 4 {'weight': 3}
2 3 {'weight': 2}
2 1 {'weight': 1}
3 1 {'weight': 5}

再试一下adjlist格式:

G = nx.Graph()
G.add_edges_from([(2, 4), (2, 3), (2, 1), (1, 3)])
nx.write_adjlist(G, "./graph.adjlist")
G2 = nx.read_adjlist("./graph.adjlist")

查看adjlist格式结果,adjlist是由头元素+尾序列组成的,头元素和尾序列的每一个作为边的两边的节点,不论adjlist还是edgelist,所有节点对都只算1次,交换位置不重复记录,但是在读取的时候可以自由转为有向图和无向图:

2 4 3 1
4
3 1
1

默认读取是Graph无向图,如果要读取成有向图,在read方法中指定参数create_using=nx.DiGraph:

G = nx.DiGraph()
G.add_edges_from([(2, 4), (2, 3), (2, 1), (1, 3)])
nx.write_adjlist(G, "./graph.adjlist")
G2 = nx.read_adjlist("./graph.adjlist")
list(G2.neighbors('1'))  # ['2', '3']
G3 = nx.read_adjlist("./graph.adjlist", create_using=nx.DiGraph)
list(G3.neighbors('1'))  # ['3']

需要注意的是如果保存文件的时候节点是数值对象,读进来之后节点都会自动转化为字符串,如果要指定节点数据类型,需要在read方法中增加参数比如nodetype=int

G2 = nx.read_adjlist("./graph.adjlist", nodetype=int)
list(G2.neighbors(1))  # ['2', '3']

11. 多图

NetworkX 提供了允许任意一对节点之间存在多条边的图类。 MultiGraph 和 MultiDiGraph 类允许您添加相同的边两次,可能使用不同的边数据。 这对于某些应用程序来说可能很强大,但许多算法在此类图上没有很好地定义。 在结果定义明确的地方,例如 MultiGraph.degree() 我们提供了函数。 否则,您应该以使测量明确定义的方式转换为标准图表。

MG = nx.MultiGraph()
MG.add_weighted_edges_from([(1,2,0.5),(1,2,0.75),(2,3,0.5)])
dict(MG.degree(weight='weight'))  
# {1: 1.25, 2: 1.75, 3: 0.5}
GG = nx.Graph()
for n, nbrs in MG.adjacency():
    for nbr, edict in nbrs.items():
        minvalue = min([d['weight'] for d in edict.values()])
        GG.add_edge(n, nbr, weight=minvalue)
nx.shortest_path(GG, 1,3)
# [1, 2, 3]

参考资料

[1] 图论的基本理论
[2] Network Tutorial
[3] 复杂网络基础知识以及Networkx官方文档学习使用

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

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

相关文章

基于javaweb框架的springboot mybatis宠物商城源码含论文设计文档

在互联网高速发展、信息技术步入人类生活的情况下&#xff0c;电子贸易也得到了空前发展。网购几乎成为了人人都会进行的活动。近几年来&#xff0c;养宠物更是成为人们生活中重要的娱乐内容之一&#xff0c; 人们越来越多的讲感情也寄托给了宠物&#xff0c;以给自己另一个感情…

自动驾驶--预测技术

根据百度技术培训中心课程整理( https://bit.baidu.com/productsBuy?id72) 背景简介 无人车系统从算法模块可分为三个部分&#xff0c;首先是感知通过对传感器数据和环境信息进行计算来解决周围有什么的问题&#xff0c;其次是预测&#xff0c;根据感知信息预测环境下一步将…

Java单元测试

1. 序言 1.1 工作中要求进行单元测试 毕业进入公司时&#xff0c;为了锻炼笔者的Java基础&#xff0c;老大给笔者分配了平台化开发的工作&#xff0c;基于Spring Boot Mybatis的Java Web后端开发一个人干后端开发&#xff0c;且以前也没有后端开发的经验&#xff0c;所以只是…

CTF之序列化__toString

序列化简介 本质上serialize()和unserialize&#xff08;&#xff09;在php内部的实现上是没有漏洞的&#xff0c;漏洞的主要产生是由于应用程序在处理对象&#xff0c;魔术函数以及序列化相关问题时导致的。 当传给unserialize()的参数可控时&#xff0c;那么用户就可以注入精…

【应用】Docker Swarm

Docker SwarmDocker Swarm 集群配置配置前准备初始化 SwarmSwarm 常用命令Portainer 集群管理Docker Swarm 集群配置 masternode1node2192.168.86.133192.168.86.131192.168.86.139 配置前准备 关闭各个节点服务器的防火墙 systemctl stop firewalld systemctl disable fire…

ATF问题二则:EL3可能没有实现吗? aarch32中的S-EL1是什么?

最近两个问题&#xff0c;戳到了我的知识盲点&#xff0c;当然我这个菜鸡ATF哪里都是盲点。 问题一&#xff1a;EL3可能没有实现吗&#xff1f; 问题二&#xff1a;bl2是aarch32, 那么bl2是S-EL1&#xff0c;bl31也是S-EL1? 1、EL3可能没有实现吗&#xff1f; The Armv8-A …

基于MATLAB的一级倒立摆控制仿真,带GUI界面操作显示倒立摆动画,控制器控制输出

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 一个可以活动的小车上立着一根不稳定随时会倒下的杆。小车的轮子由电机控制&#xff0c;可以控制小车电机的转动力矩M。同时&#xff0c;也可以获取小车轮子转动的圈数N&#xff08;可以精确到小…

java计算机毕业设计ssm实验室设备管理系统5k648(附源码、数据库)

java计算机毕业设计ssm实验室设备管理系统5k648&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xf…

162.基于Django-rest_framework的身份验证和权限

1. 概述 到目前为止&#xff0c;程序的API对任何人都可以编辑或删除&#xff0c;没有任何限制。我们希望有一些更高级的行为&#xff0c;进行身份验证和权限分配&#xff0c;以确保&#xff1a; 数据始终与创建者相关联只有经过身份验证的用户才能创建数据只有数据的创建者可…

嵌入式Linux上ifpulgd的使用配置与qemu模拟验证

问题引入 最近在项目开发中收到了一个非常简单的需求&#xff0c;我们的嵌入式Linux板卡需要在检测到网口插拔后重新配置网络&#xff0c;这在pc环境中非常常见。但是在这个项目的默认SDK中并没有相关配置&#xff0c;稍微查询了一下&#xff0c;在一般pc上通常使用Ifpulgd,并…

[附源码]Python计算机毕业设计Django企业售后服务管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【数据结构】树的概念与堆的实现

树的概念与堆的实现1、什么是树1.1 树的概念1.2 树的相关概念1.3 树的表示2、二叉树概念及结构2.1 概念2.2 特殊的二叉树2.3 二叉树的性质2.4 二叉树的存储结构3、二叉树的顺序结构及实现3.1 二叉树的顺序结构3.2 堆的概念及结构3.3 堆的实现3.3.1 创建一个堆3.3.2 初始化堆3.3…

【计算机毕业设计】基于JSP的网上购物系统的设计与实现

分类号&#xff1a;TP315 U D C&#xff1a;D10621-408-(2007)5883-0 密 级&#xff1a;公 开 编 号&#xff1a;2003214012 学位论文 基于JSP的网上购物系统的设计与实现 基于JSP的网上购物系统的设计与实现 摘 要 近年来&#xff0c;随着Internet的迅速崛起&#xff0c…

内存 分页、交换空间

目录 1. 分页 1.1 地址转换 1.2 页表存在哪里 1.3 列表中究竟有什么 1.4 分页的优缺点 2. 快速地址转换&#xff08;TLB&#xff09; 2.1 TLB 的基本算法 2.2 谁来处理 TLB 未命中 2.2.1 硬件处理 2.2.2 软件&#xff08;操作系统&#xff09;处理 2.3 TLB 的内容 …

[附源码]Python计算机毕业设计SSM精准扶贫系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

(免费分享)基于springboot,vue公司财务系统

该系统是一个简单的公司财务管理系统&#xff0c;包含用户基本信息管理&#xff08;员工管理&#xff0c;管理员管理&#xff09;&#xff0c;工资管理&#xff08;员工工资管理&#xff0c;管理员工资管理&#xff09;&#xff0c;业务管理&#xff08;员工业务管理&#xff0…

Windows server 2012搭建用户隔离FTP站点

Windows server 2012搭建用户隔离FTP站点 系统添加FTP功能创建FTP登陆账户和其使用的文件夹D盘根目录下创建FTP站点主目录ftp文件夹ftp下创建用户主目录localuser&#xff08;名称不可更改&#xff0c;实现用户隔离必要步骤&#xff09;Localuser文件夹下创建对应用户的文件夹…

opencv入门笔记(二)

目录图像运算位运算位与运算位或运算取反运算异或运算位运算特点示例&#xff1a;位运算示例加法运算示例&#xff1a;查看三种加法运算的区别滤波器均值滤波中值滤波高斯滤波双边滤波示例&#xff1a;查看多种滤波器的处理效果视频处理示例&#xff1a;打开笔记本电脑内置摄像…

轻量化神经网络(移动设备上的神经网络)的整体框架

提示&#xff1a;不断更新中 文章目录一、为什么要引入轻量化神经网络二、模型压缩(Model Compression)参数修建低秩因子分解参数量化知识蒸馏人工神经架构设计三、自动压缩和神经架构搜索(Automated Compression and Neural Architecture Search)自动模型压缩(Automated Model…

【软件工程】白盒测试:基本路径测试

基本路径测试是在程序控制流图的基础上&#xff0c;通过分析控制构造的环路复杂性&#xff0c;导出基本可执行的路径集合&#xff0c;从而设计测试用例的方法。 步骤(以一段代码为例)&#xff1a; &#xff08;1&#xff09;画出控制流图 void sort(int num,int t) 1. { 2. i…