图神经网络学习之路——图的重要概念以及networkx的使用

1、图的属性

1.1 如何在数学上表示一个图

通常,我们使用符号 G G G来代表一个图(Graph)。

由于图是由节点(vertex / node)和边(edge / link)所组成,所以使用集合 { V , E } \{V, E\} {V,E}来表示图,即 G = { V , E } G=\{V, E\} G={V,E}。其中 V = { v 1 , v 2 , . . . , v N } V=\{v_1,v_2,...,v_N\} V={v1,v2,...,vN},是节点的集合,节点数量为 N N N E = { e 1 , e 2 , . . . , e M } E=\{e_1,e_2,...,e_M\} E={e1,e2,...,eM}是边的集合,边的数量为 M M M。连接两个节点 v 1 v_1 v1 v 2 v_2 v2的边可以表示为 e = ( v 1 , v 2 ) e=(v_1,v_2) e=(v1,v2)

如图所示,是一个节点数 N = 5 N=5 N=5,边数 M = 6 M=6 M=6的图。其可以表示为: G = { V , E } , V = { v 1 , v 2 , v 3 , v 4 , v 5 } , E = { e 1 , e 2 , e 3 , e 4 , e 5 , e 6 } G=\{V,E\}, \quad V=\{v_1,v_2,v_3,v_4,v_5\},\quad E=\{e_1,e_2,e_3,e_4,e_5,e_6\} G={V,E},V={v1,v2,v3,v4,v5},E={e1,e2,e3,e4,e5,e6}


图1-1. 无向图

在图中,节点和边是可以包含信息的。常见的信息包括两种,分别是类别型数值型。类别型的数据的取值只能是哪一类别,一般称类别型的信息为标签(label);数值型数据的取值范围为实数。一般称数值型的信息为属性(attribute)。一般认为节点一定含有信息(至少含有节点的度的信息),边可能含有信息

1.2 图的分类

根据不同的划分规则,图可以被划分为多种类型。常见的划分方式有以下几种。

1.2.1 有向图和无向图

根据图中的边是否具有指向性,可以分为有向图和无向图。图1-1就是无向图,而图1-2是有向图。


图1-2. 有向图

1.2.2 有权图和无权图

根据图的边上权重是否为 1 1 1,我们可以将它们分为:

  • 图的边上的权重为 1 1 1 时,它是一个无权图(unweighted graph)。
  • 图的边上的权重不为 1 1 1 的时候,它是一个有权图(weighted graph)。我们记点 v i v_i vi v j v_j vj 的权重为 w i j w_{ij} wij.

图1-3. 无权图(左)和有权图(右)

1.2.3 同质图和异质图

  • 同质图(Homogeneous Graph):只有一种类型的节点和一种类型的边的图。
  • 异质图(Heterogeneous Graph):存在多种类型的节点和多种类型的边的图。

1.2.4 其他分类方法

除了上述广为人知的分类方法,还可以根据拓扑结构对图进行分类,还有二分图等。因为暂时用不到,这里就不介绍了。

1.3 图的性质

1.3.1 相邻节点

图的相邻节点包含两类:直接相连的相邻节点和 k k k跳远的相邻节点。

  • 节点 v i v_i vi 的相邻节点(neighbors)是与节点 v i v_i vi 直接相连的节点,其被记为 N ( v i ) {N(v_i)} N(vi)
  • 节点 v i v_i vi k k k 跳远的相邻节点(neighbors with k k k-hop)是到节点 v i v_i vi 要走 k k k 步的节点。又称为k-hop。一个节点1-hop的相邻节点是与这个节点直接相连的全部节点 [ 1 ] ^{[1]} [1],k-hop算法采用的是宽度优先搜索(BFS)的方式。。

例如,在图1-1中,节点 v 1 v_1 v1的相邻节点 N ( v 1 ) = { v 2 , v 3 , v 5 } N(v_1)=\{v_2,v_3,v_5\} N(v1)={v2,v3,v5}。节点 v 1 v_1 v1的2跳远的节点为: { v 4 } \{v_4\} {v4}。计算过程为:

  1. 从节点 v 1 v_1 v1出发,首先访问所有1-hop邻居,即直接与 v 1 v_1 v1相连的节点,这里是节点 v 2 v_2 v2、节点 v 3 v_3 v3和节点 v 5 v_5 v5
  2. 对于节点 v 2 v_2 v2的邻居,我们访问节点 v 3 v_3 v3(但节点 v 3 v_3 v3已经是 v 1 v_1 v1的1-hop邻居,所以不计入2-hop邻居)。
  3. 对于节点 V 3 V_3 V3的邻居,我们访问节点 v 4 v_4 v4 v 1 − v 3 − v 4 v_1-v_3-v_4 v1v3v4是两跳)和节点 v 5 v_5 v5(但节点 v 5 v_5 v5已经是 v 1 v_1 v1的1-hop邻居,所以不计入2-hop邻居)。
  4. 对于节点 v 5 v_5 v5的邻居,我们访问节点 v 3 v_3 v3(但节点 v 3 v_3 v3已经是 v 1 v_1 v1的1-hop邻居,所以不计入2-hop邻居)。

1.3.2 节点的度

节点 v i v_i vi 的度记为 d ( v i ) d(v_i) d(vi),入度记为 d i n ( v i ) d_{in}(v_i) din(vi),出度记为 d o u t ( v i ) d_{out}(v_i) dout(vi)

  • 对于有向有权图:节点 v i v_i vi 的出度(out degree)等于从 v i v_i vi 出发的边的权重之和;节点 v i v_i vi 的入度(in degree)等于从连向 v i v_i vi 的边的权重之和。
  • 有向无权图是有权图的特殊情况,各边的权重为 1 1 1,那么节点 v i v_i vi 的出度(out degree)等于从 v i v_i vi 出发的边的数量,节点 v i v_i vi 的入度(in degree)等于从连向 v i v_i vi 的边的数量。
  • 无向有权图无向无权图是有向图的特殊情况,节点的出度与入度相等。

1.3.3 平均度和度分布

平均度是一个表达网络整体性质重要的参数,等于所有节点度的平均值。对于无向无权图来说,其节点数量为 N N N,边的数量为 M M M。由于其出度=入度,所以平均度的计算公式为:
d ˉ ( G ) = 1 N ∑ i = 1 N d i = 2 M N \bar{d}({G})=\frac{1}{N}\sum^{N}_{i=1}d_i=\frac{2M}{N} dˉ(G)=N1i=1Ndi=N2M

度分布 P ( d ) P(d) P(d) 表示随机选择的节点的度为 d d d 的概率,平均度即度的期望:
d ˉ ( G ) = ∑ d = 0 ∞ d P ( d ) \bar{d}({G})=\sum_{d=0}^{\infty} dP(d) dˉ(G)=d=0dP(d)

1.3.4 walk和path

G G G的一条通路(walk)是指一条由顶点与边组成的交错序列 [ 2 ] ^{[2]} [2]:
v 1 , e 1 , e 2 , v 2 , e 3 , . . . v_1,e_1,e_2,v_2,e_3,... v1,e1,e2,v2,e3,...
里面的顶点和边都可以重复。
例如,下图中, w a l k ( v 1 , v 2 ) = ( v 1 , e 5 , e 4 , e 6 , v 1 , e 1 , v 2 ) walk(v_1,v_2)=(v_1,e_5,e_4,e_6,v_1,e_1,v_2) walk(v1,v2)=(v1,e5,e4,e6,v1,e1,v2),这是一次walk,红色线条标识了边的访问顺序。这里要注意,并不是意味着从 v 1 v_1 v1 v 2 v_2 v2一定要这样走,这只是一个walk。

而一个path中,节点是不可重复的。即path是节点不可重复的walk。


图1-4. walk示意图

1.3.5 距离(distance)和直径(diameter)

最短路径(shortest path)被定义为两个点之间的距离(distance)。

最短路径 v s , v t ∈ V v_{s}, v_{t} \in {V} vs,vtV 是图 G = { V , E } {G}=\{{V}, {E}\} G={V,E} 上的一对节点,节点对 v s , v t ∈ V v_{s}, v_{t} \in {V} vs,vtV 之间所有路径的集合记为 p s t p_{st} pst。节点对 v s , v t v_{s}, v_{t} vs,vt 之间的最短路径 p s t s p p_{st}^{sp} pstsp p s t p_{st} pst 中长度最短的一条路径,其形式化定义为
p s t s p = a r g m i n p ∈ P s t ∣ p ∣ p_{st}^{sp}= argmin_{p \in P_{st}}|p| pstsp=argminpPstp
其中, p p p表示 p s t p_{st} pst 中的一条路径, ∣ p ∣ |p| p是路径 p p p的长度。

  • 直径(diameter):给定一个连通图 G = { V , E } {G}=\{{V}, {E}\} G={V,E},其直径为其所有节点对之间的最短路径的最大值,形式化定义为

d i a m e t e r ( G ) = m a x v s , v t ∈ V m i n p ∈ p s t ∣ p ∣ diameter({G})=max_{v_{s}, v_{t} \in {V}} min_{p \in p_{s t}}|p| diameter(G)=maxvs,vtVminppstp

1.3.6 子图(subgraph)、连通分量(connected component)、连通图(connected graph)

  • 子图(subgraph):有一图 G = { V , E } {G}=\{{V}, {E}\} G={V,E} ,另有一图 G ′ = { V ′ , E ′ } {G}^{\prime}=\{{V}^{\prime}, {E}^{\prime}\} G={V,E} ,其中 V ′ ∈ V {V}^{\prime} \in {V} VV E ′ ∈ E {E}^{\prime} \in {E} EE 并且 V ′ {V}^{\prime} V 不包含 E ′ {E}^{\prime} E 中未出现过的节点,那么 G ′ {G}^{\prime} G G {G} G 的子图。
  • 连通分量(connected component):给定图 G ′ = { V ′ , E ′ } {G}^{\prime}=\{{V}^{\prime}, {E}^{\prime}\} G={V,E} 是图 G = { V , E } {G}=\{{V}, {E}\} G={V,E} 的子图。记属于图 G {G} G 但不属于 G ′ {G}^{\prime} G 图的节点集合记为 V ∖ V ′ {V} \setminus {V}^{\prime} VV 。如果属于 V ′ {V}^{\prime} V 的任意节点对之间存在至少一条路径,但不存在一条边连接属于 V ′ {V}^{\prime} V 的节点与属于 V ∖ V ′ {V} \setminus {V}^{\prime} VV 的节点,那么图 G ′ {G}^{\prime} G 是图 G {G} G 的连通分量。
  • 连通图(connected graph):当一个图只包含一个连通分量,即其自身,那么该图是一个连通图。

1.3.7 聚类系数和接近中心度

emmm,暂时我也没用到过这两个概念,所以就写一下定义。如果后续用到了再好好学一下。

  • 聚类系数表示给定节点的邻居彼此链接的程度
  • 节点 i i i 的邻域互连越紧密,其局部聚类系数越高。
  • C i C_i Ci 是节点的两个邻居相互链接的概率。
  • 对于度数为 d i d_i di 的节点 i,局部聚类系数定义为
    C i = E i T i C_i=\frac{E_i}{T_i} Ci=TiEi

其中, E i E_i Ei 表示节点 i i i 的邻居实际存在的边的数量, T i T_i Ti 表示节点 i i i 的邻居可能(最多)存在的边的数量。

  • C i = 0 C_i = 0 Ci=0 如果节点 i 的邻居都没有相互链接。

  • C i = 1 C_i = 1 Ci=1 如果节点 i 的邻居形成一个全连接图,即它们都相互链接。

  • C i = 0.5 C_i = 0.5 Ci=0.5 意味着一个节点的两个邻居有 50 % 50\% 50% 的机会链接。

  • 网络的聚类系数平均聚类系数:是所有节点的集聚系数的平均值为
    C = 1 N ∑ i C i C=\frac{1}{N}\sum_i C_i C=N1iCi

  • 在连通图中,节点的接近中心性(或接近性)是网络中中心性的度量,计算为该节点与图中所有其他节点之间的最短路径长度之和的倒数。

  • 节点越中心,它与所有其他节点越接近。

  • 接近中心度的计算公式为
    c ( v ) = 1 ∑ u ≠ v shortest path length between  u  and  v c(v) = \frac{1}{\sum_{u \neq v}\text{shortest path length between } u \text{ and } v} c(v)=u=vshortest path length between u and v1

1.4 图的连接表示

这里介绍三种图的连接表示:邻接矩阵、关联矩阵和拉普拉斯矩阵。

1.4.1 邻接矩阵(Adjacency Matrix)

  • 给定一个无权图 G = { V , E } {G}=\{{V}, {E}\} G={V,E},其对应的邻接矩阵被记为 A ∈ { 0 , 1 } N × N \mathbf{A} \in\{0,1\}^{N \times N} A{0,1}N×N A i , j = 1 \mathbf{A_{i,j}}=1 Ai,j=1 表示存在从节点 v i v_i vi v j v_j vj 的边, A i , j = 0 \mathbf{A}_{i, j}=0 Ai,j=0 表示不存在从节点 v i v_i vi v j v_j vj 的边。
  • 在无向图中,从节点 v i v_i vi v j v_j vj 的边存在,意味着从节点 v j v_j vj v i v_i vi 的边也存在。因而无向图的邻接矩阵是对称的
  • 在无权图中,各条边的权重被认为是等价的,即认为各条边的权重为1
  • 对于有权图,其对应的邻接矩阵通常被记为 W ∈ R N × N \mathbf{W} \in \mathbb{R}^{N \times N} WRN×N,其中 W i , j = w i j \mathbf{W_{i, j}}=w_{ij} Wi,j=wij 表示从节 v i v_i vi v j v_j vj 的边的权重。若边不存在时,边的权重为 0 0 0

图1-5. 无向无权图的邻接矩阵

图1-6. 有向有权图的邻接矩阵

1.4.2 关联矩阵(Incidence Matrix)

与邻接矩阵不同,关联矩阵描述的是定点和边之间的关系。

  • 给定一个图 G = { V , E } {G}=\{{V}, {E}\} G={V,E},其对应的关联矩阵被记为 M ∈ { − 1 , 0 , 1 } N × M \mathbf{M} \in\{-1,0,1\}^{N \times M} M{1,0,1}N×M。(这里用加粗的 M \mathbf{M} M 表示关联矩阵,用不加粗的 M M M 表示边的个数)
  • 对于无向图来说, M i , j = 1 \mathbf{M_{i, j}}=1 Mi,j=1 表示节点 v i v_i vi 和边 e j e_j ej 相连接(即顶点在边上), M i , j = 0 \mathbf{M_{i, j}}=0 Mi,j=0 表示节点 v i v_i vi 和边 e j e_j ej 不相连接。无向图里 M i , j \mathbf{M_{i,j}} Mi,j是不会为-1的。
  • 对于有向图,其 M i , j \mathbf{M_{i, j}} Mi,j的取值为 [ 3 , 4 ] ^{[3,4]} [3,4]

M i , j = { 1 , v i 是 e i 的起点 0 , v i 与 e i 不关联 − 1 , v i 是 e i 的终点 \mathbf{M_{i, j}}=\left\{ \begin{aligned} 1 &, & v_i是e_i的起点 \\ 0 &, & v_i与e_i不关联 \\ -1 &, & v_i是e_i的终点 \end{aligned} \right. Mi,j= 101,,,viei的起点viei不关联viei的终点


图1-7. 无向图的关联矩阵

图1-8. 有向图的关联矩阵

1.4.3 拉普拉斯矩阵(Laplacian Matrix)

在这里只是提一下,后面会再写一篇文章详细推导一下拉普拉斯矩阵。

拉普拉斯矩阵(Laplacian Matrix / admittance matrix, Kirchhoff matrix):给定一个图 G = { V , E } {G}=\{{V}, {E}\} G={V,E},其邻接矩阵为 A A A,其拉普拉斯矩阵 L L L 定义为
L = D − A \mathbf{L=D-A} L=DA
其中 D = d i a g ( d ( v 1 ) , ⋯   , d ( v N ) ) \mathbf{D=diag(d(v_1), \cdots, d(v_N))} D=diag(d(v1),,d(vN))是度矩阵。更具体地,我们记拉普拉斯矩阵中每一个元素为 L i j L_{ij} Lij,那么每一个元素可以被定义为:
L i , j = { d i , if i = j − 1 , if i ≠ j and  v i  adjacent with j 0 , otherwise L_{i,j}= \begin{cases} d_i & , & \text{if i = j} \\ -1 &, & \text{if i} \neq \text{j and $v_i$ adjacent with j} \\ 0 &, & \text{otherwise} \end{cases} Li,j= di10,,,if i = jif i=j and vi adjacent with jotherwise

它的每一行和列的加和为 0 0 0

对称归一化的拉普拉斯矩阵,Symmetric normalized Laplacian):给定一个图 G = { V , E } {G}=\{{V}, {E}\} G={V,E},其邻接矩阵为 A A A,其规范化(归一化)的拉普拉斯矩阵定义为

L = D − 1 2 ( D − A ) D − 1 2 = I − D − 1 2 A D − 1 2 \mathbf{L=D^{-\frac{1}{2}}(D-A)D^{-\frac{1}{2}}=I-D^{-\frac{1}{2}}AD^{-\frac{1}{2}}} L=D21(DA)D21=ID21AD21

2、networkx的使用

代码可以在github中找到:https://github.com/cannibalistic-galaxy/GraphMLStudy/tree/main/Graph%20Properties%20and%20NetworkX%20Usage

2.1 创建无向图

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np

g = nx.Graph()
# 添加图的节点
g.add_node(1)
g.add_node(2)
g.add_node(3)
g.add_node(5)
# 添加图的边
g.add_edge(1, 2)
g.add_edge(2, 3) 
g.add_edge(3, 4) # 当添加的边对应的节点不存在的时候,会自动创建相应的节点
g.add_edge(3, 5)
g.add_edge(5, 1)
g.add_edge(1, 3)

# 绘制的图带label
nx.draw(g, with_labels=True)

这里绘制出一个和图1-1一样结构的图出来:
在这里插入图片描述

2.2 创建有向图

# 判断图是否为有向图
dg = nx.DiGraph()
print(g.is_directed())
print(dg.is_directed())

输出为:

False
True
# 添加图的节点
dg.add_node(1)
dg.add_node(2)
# 添加图的边
dg.add_edge(1, 2)
dg.add_edge(2, 3) # 当添加的边对应的节点不存在的时候,会自动创建相应的节点
# 绘制有向图
nx.draw(dg, with_labels=True)

在这里插入图片描述

2.3 空手道俱乐部

空手道俱乐部是一个比较有名的数据集:

KG = nx.karate_club_graph() # 创建空手道俱乐部图
nx.draw(KG, with_labels=True)

在这里插入图片描述

2.4 图的性质

2.4.1 计算指定节点的邻接节点

neigbor = [n for n in g.neighbors(1)]
print(neigbor)

# 计算k-hop邻接节点
def get_neigbors(g, node, depth=1):
    output = {}
    layers = dict(nx.bfs_successors(g, source=node, depth_limit=depth))
    nodes = [node]
    for i in range(1,depth+1):
        output[i] = []
        for x in nodes:
            output[i].extend(layers.get(x,[]))
        nodes = output[i]
    return output[depth]

k_hop_neigbor = get_neigbors(g, 1, 2)
print("k-hop neigbors: ", k_hop_neigbor)

输出为:

[2, 5, 3]
k-hop neigbors:  [4]

2.4.2 计算节点的度

print(g.degree(1)) # 节点1的度
print(g.degree()) # 所有节点的度

输出:

3
[(1, 3), (2, 2), (3, 4), (5, 2), (4, 1)]

2.4.3 计算平均度和度分布

# 计算平均度
def average_degree(num_edges, num_nodes):
    # this function takes number of edges and number of nodes
    # returns the average node degree of the graph. 
    # Round the result to nearest integer (for example, 3.3 will be rounded to 3 and 3.7 will be rounded to 4)
    avg_degree = 0
    #########################################
    avg_degree = 2*num_edges/num_nodes
    avg_degree = int(round(avg_degree))
    #########################################
    return avg_degree

num_edges = g.number_of_edges()
num_nodes = g.number_of_nodes()
avg_degree = average_degree(num_edges, num_nodes)
print("Average degree of the given graph is {}".format(avg_degree))


print(nx.degree_histogram(g)) # 度分布

输出:

Average degree of karate club network is 2
[0, 1, 2, 1, 1]

2.4.4 聚类系数

def average_clustering_coefficient(G):
    # this function that takes a nx.Graph
    # and returns the average clustering coefficient. 
    # Round the result to 2 decimal places (for example 3.333 will be rounded to 3.33 and 3.7571 will be rounded to 3.76)
    avg_cluster_coef = 0
    #########################################
    ## Note: 
    ## 1: Please use the appropriate NetworkX clustering function
    avg_cluster_coef = nx.average_clustering(G)
    avg_cluster_coef = round(avg_cluster_coef, 2)
    #########################################
    return avg_cluster_coef

avg_cluster_coef = average_clustering_coefficient(g)
print("Average clustering coefficient of the given graph is {}".format(avg_cluster_coef))

输出:

Average clustering coefficient of the given graph is 0.6

2.4.5 接近中心度

def closeness_centrality(G, node=5):
    # the function that calculates closeness centrality 
    # for a node in karate club network. G is the input karate club 
    # network and node is the node id in the graph. Please round the 
    # closeness centrality result to 2 decimal places.

    closeness = 0
    #########################################
    # Raw version following above equation
    # source: https://stackoverflow.com/questions/31764515/find-all-nodes-connected-to-n
    path_length_total = 0 
    for path in list(nx.single_source_shortest_path(G,node).values())[1:]:
        path_length_total += len(path)-1

    closeness = 1 / path_length_total
    closeness = round(closeness, 2)

    return closeness

node = 5
closeness = closeness_centrality(g, node=node)
print("The given graph has closeness centrality (raw) {:.2f}".format(closeness))

# Normalized version from NetworkX
# Notice that networkx closeness centrality returns the normalized 
# closeness directly, which is different from the raw (unnormalized) 
# one that we learned in the lecture.
closeness = nx.closeness_centrality(g, node)
print("The given graph has closeness centrality (normalzied) {:.2f}".format(closeness))

输出为:

The given graph has closeness centrality (raw) 0.17
The given graph has closeness centrality (normalzied) 0.67

2.5 图的连接

2.5.1 计算邻接矩阵

A = np.array(nx.adjacency_matrix(g, nodelist=[1, 2, 3, 4, 5]).todense())
print(A)

输出:

[[0 1 1 0 1]
 [1 0 1 0 0]
 [1 1 0 1 1]
 [0 0 1 0 0]
 [1 0 1 0 0]]

这里要加nodelist,因为默认的nodelist顺序不是12345这样排列,就会得到和我们自己计算不一致的结果 [ 5 ] ^{[5]} [5]。默认的节点顺序为:

g.nodes()

输出:

NodeView((1, 2, 3, 5, 4))

2.5.2 计算关联矩阵

B = np.array(nx.incidence_matrix(g, nodelist=[1, 2, 3, 4, 5], edgelist=[(1, 2), (2, 3), (3, 4), (3, 5), (5, 1), (1, 3)]).todense())
print(B)

输出:

[[1. 0. 0. 0. 1. 1.]
 [1. 1. 0. 0. 0. 0.]
 [0. 1. 1. 1. 0. 1.]
 [0. 0. 1. 0. 0. 0.]
 [0. 0. 0. 1. 1. 0.]]

这里要加nodelist和edgelist,因为默认的顺序不是按顺序排列,就会得到和我们自己计算不一致的结果 [ 6 ] ^{[6]} [6]。默认的边顺序为:

g.edges()

输出:

EdgeView([(1, 2), (1, 5), (1, 3), (2, 3), (3, 4), (3, 5)])

参考资料:

[1] https://arxiv.org/abs/1907.06051

[2] http://www.atzjg.net/admin/do/view_question.php?qid=2106

[3] https://blog.csdn.net/luzaijiaoxia0618/article/details/104720948

[4] http://123.56.88.210/ppt/lisan_10.pdf

[5]https://www.osgeo.cn/networkx/reference/generated/networkx.linalg.graphmatrix.adjacency_matrix.html#google_vignette

[6]https://networkx.org/documentation/stable/reference/generated/networkx.linalg.graphmatrix.incidence_matrix.html

[6] datawhale: https://datawhalechina.github.io/grape-book/

github地址:https://github.com/cannibalistic-galaxy/GraphMLStudy/tree/main/Graph%20Properties%20and%20NetworkX%20Usage

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
大学生在线租房平台管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、报修评价管理、字典管理、房东管理、房屋管理、房屋收藏管理、房屋留言管理、房屋租赁管理、租房论坛管理、公告信息管理、留言板管理、用户管理、管理员管理。用户的功能等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 大学生在线租房平台管理系统可以提高大学生在线租房平台信息管理问题的解决效率,优化大学生在线租房平台信息处理流程,保证大学生在线租房平台信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理大学生在线租房平台信息,包括房屋管理,培训管理,报修管理,薪资管理等,可以管理公告。 房屋管理界面,管理员在房屋管理界面中可以对界面中显示,可以对房屋信息的房屋状态进行查看,可以添加新的房屋信息等。报修管理界面,管理员在报修管理界面中查看报修种类信息,报修描述信息,新增报修信息等。公告管理界面,管理员在公告管理界面中新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值