基于图结构实现北京地铁乘坐线路查询( python)

问题描述

编写一个程序实现北京地铁最短乘坐(站)线路查询,输入为起始站名目的站名,输出为从起始站到目的站的最短乘坐站换乘线路。

  1. 采用Dijkstra算法实现;
  2. 如果两站间存在多条最短路径,找出其中的一条就行

数据输入形式

文件bgstations.txt为数据文件,包含了北京地铁的线路及车站信息。其格式如下:

<地铁线路总条数><线路1> <线路1站数><站名1> <换乘状态><站名2> <换乘状态>...<线路2> <线路2站数><站名1> <换乘状态><站名2> <换乘状态>...

例如演示代码输入的数据形式:

121 23苹果园 0古城 0八角游乐园 0八宝山 0玉泉路 0五棵松 0万寿路 0公主坟 1军事博物馆 1木樨地 0南礼士路 0复兴门 1西单 1...2 19西直门 1积水潭 0鼓楼大街 1...西直门 1...该文件表明当前北京地铁共有12条线路(不含郊区线路),接着为每条线路信息。

打开当前目录下文件bgstations.txt,读入地铁线路信息,并从标准输入中读入起始站和目的站名(均为字符串,各占一行)。

数据输出形式

输出从起始站到目的站的乘坐信息,要求乘坐站数最少。换乘信息格式如下:SSN-n1(m1)-S1-n2(m2)-...-ESN其中:SSN和ESN分别为起始站名和目的站名;n为乘坐的地铁线路号,m为乘坐站数。

代码结构以及重难点分析

  1. 站名是中文字符,对于不同的编译器或者不同的操作系统,可能会导致乱码的形式出现

# try except部分代码用于修改python runtime的标准输入输出的编码格式
try:import ioimport syssys.stdin = io.TextIOWrapper(sys.stdin.detach(), encoding='utf-8')sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding='utf-8')
except:pass

# 读取地铁线路信息的函数
def read_file(filename):# 打开文件时指定编码为"utf-8"f = open(filename, 'r', encoding="utf-8")# 读取总线路数目total = int(f.readline())for _ in range(total):# 读取线路id和线路站数id, n = (int(x) for x in f.readline().split())for j in range(n):# 读取站名和换乘站信息name, is_transfer = f.readline().split()return subway_info
  1. 环线、直线、换乘
    从bgstations.txt中可以看见如下数据输入:从bgstations.txt中可以看见如下数据输入:

2 19
西直门 1
积水潭 0
鼓楼大街 1

车公庄 1
西直门 1

这说明2号线是环路,所以要在建立地铁站连线图结构的时候对环线的最短路径加以考虑。我们来看图想一下
譬如,从鼓楼大街复兴门,沿安定门方向和沿积水潭方向都可以到达,比较两者路径长度显然是后者是更优解。当然这样一想一脸懵逼 ,要怎么做呢?

我们就要来看看图结构的表达形式

简单介绍一下图

(Graph)是一种比线性表和树更为复杂的数据结构。

图结构:是研究数据元素之间的多对多的关系。在这种结构中,任意两个元素之间可能存在关系。即结点之间的关系可以是任意的,图中任意元素之间都可能相关。 图的应用极为广泛,已渗入到诸如语言学、逻辑学、物理、化学、电讯、计算机科学以及数学的其它分支。

图的基本术语

1.弧(Arc) :表示两个顶点v和w之间存在一个关系,用顶点偶对<v,w>表示。通常根据图的顶点偶对将图分为有向图和无向图。

2.有向图(Digraph): 若图G的关系集合E(G)中,顶点偶对<v,w>的v和w之间是有序的,称图G是有向图。 在有向图中,若 <v,w>∈E(G) ,表示从顶点v到顶点w有一条弧。 其中:v称为弧尾(tail)或始点(initial node),w称为弧头(head)或终点(terminal node) 。

3.无向图(Undigraph): 若图G的关系集合E(G)中,顶点偶对<v,w>的v和w之间是无序的,称图G是无向图。

4.完全无向图:对于无向图,若图中顶点数为n ,用e表示边的数目,则e ∈[0,n(n-1)/2] 。具有n(n-1)/2条边的无向图称为完全无向图。

5.完全有向图:对于有向图,若图中顶点数为n ,用e表示弧的数

目,则e∈[0,n(n-1)] 。具有n(n-1)条边的有向图称为完全有向图。
6.权(Weight):与图的边和弧相关的数。权可以表示从一个顶点到另一个顶点的距离或耗费

7.子图和生成子图:设有图G=(V,E)和G’=(V’,E’),若V’=V且E’∈E ,则称图G’是G的子图;若V’=V且E’∈E,则称图G’是G的一个生成子图。顶点的邻接(Adjacent):对于无向图G=(V,E),若边(v,w)∈E,则称顶点v和w 互为邻接点,即v和w相邻接。边(v,w)依附(incident)与顶点v和w 。

图的存储结构

  1. 邻接矩阵

    ∞ 6 2 ∞ ∞
    6 ∞ 3 4 3
    2 3 ∞ 1 ∞
    ∞ 4 3 ∞ 5
    ∞ 3 ∞ 5 ∞


# 定义邻接矩阵图类
class Graph:def __init__(self,mat,unconn=0):vnum=len(mat)for x in mat:if len(x)!=vnum:#检查是否是方阵raise ValueError("Argument for 'Graph'.")self._mat=[mat[i][:] for i in range(vnum)]#赋值mat到self._matself._unconn=unconnself._vnum=vnumdef vertex_num(self):return self._vnumdef _invalid(self,v):return 0>v or v>=self._vnumdef add_vertex(self):#并未计划支持增加顶点,所以直接定义为错误,要增加顶点需要增加一行矩阵一列raise GraphError("Adj-Matrix does not support 'add_vertex'.")def add_edge(self,vi,vj,val=1):if self._invalid(vi) or self._invalid(vj):raise GraphError(str(vi)+' or '+str(vj)+" is not a valid vertex.")self._mat[vi][vj]=valdef get_edge(self,vi,vj):if self._invalid(vi) or self._invalid(vj):raise GraphError(str(vi)+' or '+str(vj)+" is not a valid vertex.")return self._mat[vi][vj]#记录已经构造的表#用静态方法构造结点表def out_edges(self,vi):if self._invalid(vi):raise GraphError(str(vi)+" is not a valid vertex.")return self._out_edges(self._mat[vi],self._unconn)@staticmethoddef _out_edges(row,unconn):edges=[]for i in range(len(row)):if row[i]!=unconn:edges.append((i,row[i]))return edges

邻接矩阵 对于大型数据的处理很鸡肋!!
(对于本次讨论的地铁图结构来说,你会发现二百多个点,一个200*200数量极的大二维列表,每一行就几个有数,其他都是inf,对于数据处理没有卵用!!)

所有的线索都指向==》当当当当

  1. 邻接表(可以理解为字典形式,每一个顶点可以指到连接它的所有点)
# 基于邻接表定义图,继承图类,也可以直接写
class GraphAL(Graph):def __init__(self,mat=[],unconn=0):vnum=len(mat)for x in mat:if len(x)!=vnum:raise ValueError("Argument for 'GraphAL'.")self._mat=[Graph._out_edges(mat[i],unconn) for i in range(vnum)]self._vnum=vnumself._unconn=unconndef add_vertex(self):#增加新节点时安排一个新编号self._mat.append([])self._vnum+=1return self._vnum-1def add_edge(self,vi,vj,val=1):if self._vnum==0:raise GraphError("cannot add edge to empty graph")if self._invalid(vi) or self._invalid(vj):raise GraphError(str(vi) + ' or ' + str(vj) + " is not a valid vertex.")row=self._mat[vi]i=0while i<len(row):if row[i][0]==vj:#更新mat[vi][vj]的值self._mat[vi][i]=(vj,val)returnif row[i][0]>vj:#原来如果没有到vj的边,退出循环,加入边breaki+=1self._mat[vi].insert(i,(vj,val))def get_edge(self,vi,vj):if self._invalid(vi) or self._invalid(vj):raise GraphError(str(vi) + ' or ' + str(vj) + " is not a valid vertex.")for i,val in self._mat[vi]:if i==vj:return valreturn self._unconndef out_edges(self,vi):if self._invalid(vi):raise GraphError(str(vi)+" is not a valid vertex.")return self._mat[vi]

代码实现

#这里我可以直接读取并显示中文,大家不行的自己修改LINEDATA=['1','2','4','5','6','7','8','9','10','13','14','15']
STATION_NUM={}#字典,站名到数字编号的对应
data={}
datanum={} #邻接表,啊哈就先这么叫他吧
STATIO={}#字典,对应数字到站名的对应
with open("routedata.txt","r") as f:TOTAL=f.readline()for line in f.readlines():if line!='\n':line = line.rstrip('\n')line=line.split(' ')if line[0] in LINEDATA:linei=line[0]continueline[1]=lineiline0=line[0]intline=int(line[1])if intline not in data.keys():data[intline]=[line0]else:data[intline].append(line0)if line0 not in datanum.keys():datanum[line0]=[intline]else:datanum[line0].append(intline)for datai in datanum.keys():STATION_NUM[datai]=iSTATIO[i]=dataii+=1I=i    # 顶点个数#判断是否为环线
def iscircle(mlist):if mlist[0]==mlist[-1]:return Truereturn False
data:{1: ['苹果园', '古城', '八角游乐园', '八宝山', '玉泉路', '五棵松', '万寿路', '公主坟'...
datanum:{'苹果园': [1], '古城': [1], '八角游乐园': [1], '八宝山': [1], '玉泉路': [1], '五棵松': [1], '万寿路': [1], '公主坟': [1, 10]...
STATION-NUM:{'苹果园': 0, '古城': 1, '八角游乐园': 2, '八宝山': 3, '玉泉路': 4, '五棵松': 5, '万寿路': 6, '公主坟': 7...

最短路径搜索

如题,采用Dijkstra算法实现

#基于优先队列的dijkstra算法
def dijkstra_shortest_pathS(graph,v0,endpos):vnum=0for i in pathss.keys():vnum+=1# print(vnum)# vnum=graph.vertex_num()assert 0<=v0<vnumpaths=[None]*vnum#长为vnum的表记录路径count=0cands=PrioQueue([(0,v0,v0)])#求解最短路径的候选边集记录在优先队列cands中(p,v,v')v0经过v到v'的最短路径长度为p,根据p的大小排序,保证选到最近的未知距离顶点while count<vnum and not cands.is_empty():plen,u,vmin=cands.dequeue()#取路径最短顶点# print(u,vmin)if paths[vmin]:#如果这个点的最短路径已知,则跳过continuepaths[vmin]=(u,plen)#新确定最短路径并记录for v in graph[vmin]:#遍历经过新顶点组的路径if not paths[v]:#如果还不知道最短路径的顶点的路径,则记录cands.enqueue((plen+1,vmin,v))count+=1# print(paths)return paths

我注释的挺清楚了,具体了解的话可以看这篇
https://www.cnblogs.com/jason2003/p/7222182.html

注意的是这里输入的graph参数如下定义:

pathss={}
for i in range(I):for j in range(I):if RouteGraph.get_edge(i,j)==1:start=STATIO[i]end=STATIO[j]if i not in pathss.keys():pathss[i]=[j]else:pathss[i].append(j)

【样例输入】

西土城

北京西站

【样例输出】

西土城-10(1)-知春路-13(2)-西直门-4(2)-国家图书馆-9(4)-北京西站

(或西土城-10(1)-知春路-13(2)-西直门-2(1)-车公庄-6(2)-白石桥南-9(3)-北京西站)

源代码放在评论里了,欢迎大家讨论与优化

完整代码:

import sys
import io
sys.stdout=io.TextIOWrapper(sys.stdout.detach(),encoding='utf-8')
sys.stdin=io.TextIOWrapper(sys.stdin.detach(),encoding='utf-8')
LINEDATA=['1','2','4','5','6','7','8','9','10','13','14','15']
STATION_NUM={}
data={}
datanum={}
# with open("routedata.txt","rb") as f:
#     for line in f.readlines():
#         print(line.decode('utf-8'))
with open("routedata.txt","r") as f:TOTAL=f.readline()for line in f.readlines():if line!='\n':line = line.rstrip('\n')line=line.split(' ')if line[0] in LINEDATA:linei=line[0]continueline[1]=lineiline0=line[0]intline=int(line[1])if intline not in data.keys():data[intline]=[line0]else:data[intline].append(line0)if line0 not in datanum.keys():datanum[line0]=[intline]else:datanum[line0].append(intline)
i=0
STATIO={}
for datai in datanum.keys():STATION_NUM[datai]=iSTATIO[i]=dataii+=1
# print(STATION_NUM)#对应到邻接矩阵的引索上
I=i
#判断是否为环线
def iscircle(mlist):if mlist[0]==mlist[-1]:return Truereturn False# print(data)
# print(datanum)
# print(STATION_NUM)#判断是否为换乘点
def istransport(station):if len(datanum[station])>1:return Truereturn False
#得到换线路
def destransport(station):return datanum[station]
# print(datanum)
def changeline(p1,p2):line1=datanum[p1]line2=datanum[p2]a=[]# print(data[line1[0]])for i1 in data[line1[0]]:if istransport(i1):ways=destransport(i1)for i2 in line2:if i2 in ways:a.append(i1)return i1return None
class GraphError(ValueError):pass
class Graph:def __init__(self,mat,unconn=0):vnum=len(mat)for x in mat:if len(x)!=vnum:#检查是否是方阵raise ValueError("Argument for 'Graph'.")self._mat=[mat[i][:] for i in range(vnum)]#赋值mat到self._matself._unconn=unconnself._vnum=vnumdef vertex_num(self):return self._vnumdef _invalid(self,v):return 0>v or v>=self._vnumdef add_vertex(self):#并未计划支持增加顶点,所以直接定义为错误,要增加顶点需要增加一行矩阵一列raise GraphError("Adj-Matrix does not support 'add_vertex'.")def add_edge(self,vi,vj,val=1):if self._invalid(vi) or self._invalid(vj):raise GraphError(str(vi)+' or '+str(vj)+" is not a valid vertex.")self._mat[vi][vj]=valdef get_edge(self,vi,vj):if self._invalid(vi) or self._invalid(vj):raise GraphError(str(vi)+' or '+str(vj)+" is not a valid vertex.")return self._mat[vi][vj]#记录已经构造的表#用静态方法构造结点表def out_edges(self,vi):if self._invalid(vi):raise GraphError(str(vi)+" is not a valid vertex.")return self._out_edges(self._mat[vi],self._unconn)@staticmethoddef _out_edges(row,unconn):edges=[]for i in range(len(row)):if row[i]!=unconn:edges.append((i,row[i]))return edges
class GraphAL(Graph):def __init__(self,mat=[],unconn=0):vnum=len(mat)for x in mat:if len(x)!=vnum:raise ValueError("Argument for 'GraphAL'.")self._mat=[Graph._out_edges(mat[i],unconn) for i in range(vnum)]self._vnum=vnumself._unconn=unconndef add_vertex(self):#增加新节点时安排一个新编号self._mat.append([])self._vnum+=1return self._vnum-1def add_edge(self,vi,vj,val=1):if self._vnum==0:raise GraphError("cannot add edge to empty graph")if self._invalid(vi) or self._invalid(vj):raise GraphError(str(vi) + ' or ' + str(vj) + " is not a valid vertex.")row=self._mat[vi]i=0while i<len(row):if row[i][0]==vj:#更新mat[vi][vj]的值self._mat[vi][i]=(vj,val)returnif row[i][0]>vj:#原来如果没有到vj的边,退出循环,加入边breaki+=1self._mat[vi].insert(i,(vj,val))def get_edge(self,vi,vj):if self._invalid(vi) or self._invalid(vj):raise GraphError(str(vi) + ' or ' + str(vj) + " is not a valid vertex.")for i,val in self._mat[vi]:if i==vj:return valreturn self._unconndef out_edges(self,vi):if self._invalid(vi):raise GraphError(str(vi)+" is not a valid vertex.")return self._mat[vi]
import numpy as np
# mat=np.zeros([i,i])
mat=np.full([i,i],np.inf)
RouteGraph=Graph(mat)
# print(data)
# print(STATION_NUM)
# print(datanum)
routee={}
for key in data.keys():datai=data[key]# print(datai)for i in range(1,len(datai)-1):# RouteGraph.add_vertex()v1=STATION_NUM[datai[i]]v2=STATION_NUM[datai[i+1]]v3=STATION_NUM[datai[i-1]]RouteGraph.add_edge(v1, v2, 1)RouteGraph.add_edge(v2, v1, 1)RouteGraph.add_edge(v3, v1, 1)RouteGraph.add_edge(v1, v3, 1)if iscircle(datai):# RouteGraph.add_vertex()v1=STATION_NUM[datai[0]]v2=STATION_NUM[datai[-2]]RouteGraph.add_edge(v1, v2, 1)RouteGraph.add_edge(v2, v1, 1)def all_shortest_path(graph):import numpy as npvnum=graph.vertex_num()a=[[graph.get_edge(i,j) for j in range(vnum)]for i in range(vnum)]nvertex=[[-1 if a[i][j]==np.inf else j for j in range(vnum)]for i in range(vnum)]for k in range(vnum):for i in range(vnum):for j in range(vnum):if a[i][j]>a[i][k]+a[k][j]:a[i][j] = a[i][k] + a[k][j]nvertex[i][j]=nvertex[i][k]return(a,nvertex)
def find_shortest_path(graph, start, end, path=[]):'查找最短路径'path = path + [start]if start == end:return pathif not start in graph.keys():return Noneshortest = Nonefor node in graph[start]:if node not in path:newpath = find_shortest_path(graph, node, end, path)if newpath:if not shortest or len(newpath) < len(shortest):shortest = newpathreturn shortest
def find_all_paths(graph, start, end, path):'查找所有的路径'path = path + [start]if start == end:return [path]if not start in graph.keys():return []paths = []for node in graph[start]:if node not in path:newpaths = find_all_paths(graph, node, end, path)for newpath in newpaths:paths.append(newpath)return pathsclass PrioQueueError(ValueError):pass
#基于堆的优先队列类,在尾端加入元素,首端作为堆顶,见peek等
class PrioQueue:def __init__(self,elist=[]):self._elems=list(elist)if elist:self.buildheap()def buildheap(self):end=len(self._elems)for i in range(end//2,-1,-1):self.siftdown(self._elems[i],i,end)def is_empty(self):return not self._elemsdef peek(self):if self.is_empty():raise PrioQueueError("in peek")return self._elems[0]def enqueue(self,e):self._elems.append(None)self.siftup(e,len(self._elems)-1)def siftup(self,e,last):elems,i,j=self._elems,last,(last-1)//2while i>0 and e<elems[j]:elems[i]=elems[j]i,j=j,(j-1)//2elems[i]=edef dequeue(self):if self.is_empty():raise PrioQueueError("in dequeue")elems=self._elemse0=elems[0]e=elems.pop()if len(elems)>0:self.siftdown(e,0,len(elems))return e0def siftdown(self,e,begin,end):elems,i,j=self._elems,begin,begin*2+1while j<end:if j+1<end and elems[j+1]<elems[j]:j+=1if e<elems[j]:breakelems[i]=elems[j]i,j=j,2*j+1elems[i]=e
#Dijkstra算法实现最短路径查找
pathss={}
for i in range(I):for j in range(I):if RouteGraph.get_edge(i,j)==1:start=STATIO[i]end=STATIO[j]if i not in pathss.keys():pathss[i]=[j]else:pathss[i].append(j)
print(pathss)
def dijkstra_shortest_pathS(graph,v0,endpos):vnum=0for i in pathss.keys():vnum+=1# print(vnum)# vnum=graph.vertex_num()assert 0<=v0<vnumpaths=[None]*vnum#长为vnum的表记录路径count=0cands=PrioQueue([(0,v0,v0)])#求解最短路径的候选边集记录在优先队列cands中(p,v,v')v0经过v到v'的最短路径长度为p,根据p的大小排序,保证选到最近的未知距离顶点while count<vnum and not cands.is_empty():plen,u,vmin=cands.dequeue()#取路径最短顶点# print(u,vmin)if paths[vmin]:#如果这个点的最短路径已知,则跳过continuepaths[vmin]=(u,plen)#新确定最短路径并记录for v in graph[vmin]:#遍历经过新顶点组的路径if not paths[v]:#如果还不知道最短路径的顶点的路径,则记录cands.enqueue((plen+1,vmin,v))count+=1# print(paths)return pathsstartpos=input()
endpos=input()
s1=STATION_NUM[startpos]
e1=STATION_NUM[endpos]
# print(s1,e1)
paths=dijkstra_shortest_pathS(pathss,s1,e1)
# print(paths)
b=[]
p=paths[e1][0]
b.append(STATIO[p])
while True:p1=paths[p][0]p=p1b.append(STATIO[p])if p==s1:break
b.reverse()
# print(b)
if len(datanum[b[0]])==1:lines=datanum[b[0]][0]
else:for i in datanum[b[0]]:for j in datanum[b[1]]:if i==j:lines=i
# print(lines)
ways=[]
ways.append([b[0],lines])
# print(STATION_NUM)
for i in range(len(b)-1):li=datanum[b[i]]if len(li)>1:for j in li:if j!=lines and j in datanum[b[i+1]]:lines=jways.append([b[i],lines])
ways.append([STATIO[e1]])
for i in range(len(ways)-1):length=paths[STATION_NUM[ways[i+1][0]]][1]-paths[STATION_NUM[ways[i][0]]][1]print(ways[i][0],end='')print('-', end='')print(ways[i][1], end='')print('(', end='')print(length, end='')print( ')', end='')if i!=len(ways)-1:print('-',end='')
print(ways[-1][0])

地铁两站之间最短路径查询(python实现)相关推荐

  1. java地铁最短距离_动手构建地铁关系网,实现最短路径查询

    一.前言 打开手机'北京地铁'APP,输入起始点:霍营,终点:北京南站,发现系统给我们推荐了两条路线. 最短时间路线与最少换乘路线,并且分别给出了耗时与乘坐里程费.看到这里,不禁开启了靓仔疑问,假如给 ...

  2. 二叉树中两节点之间最短路径

    折腾了一下午,在参考 liuyi1207164339帖子和 ethannnli的帖子的基础上搞定了这个问题.刚开始头真的大了,感觉有点超出能力范围了.分析了他们的思路,求解这个二叉树中两节点的最短路径 ...

  3. PostgreSQL+PostGIS实现两坐标点之间最短路径查询算法函数(地图工具篇.12)

    听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 前置博客地址: 11.(地图工具篇)PostgreSQL+PostGIS实现最短路径分析 1.测试验证 select routi ...

  4. python2.7和3.5相互兼容吗_Python2.7和Python3.5是两个不同版本的Python,它们之间并不相互兼容。...

    Python2.7和Python3.5是两个不同版本的Python,它们之间并不相互兼容. 答:错 地铁售票处 (英文):____ 答:subway ticket office;underground ...

  5. Python计算两日期之间排除节假日与非上班时间的工作时间

    Python计算两日期之间排除节假日与非上班时间的工作时间 前言 一.基本思路 二.代码示例 总结 文章目录 前言 一.基本思路 二.代码示例 总结 前言 工作中遇见需要写UDF计算事项办理时间的需求 ...

  6. 棋盘最短路径 python_Dijkstra 最短路径算法 Python 实现

    Dijkstra 最短路径算法 Python 实现 问题描述 使用 Dijkstra 算法求图中的任意顶点到其它顶点的最短路径(求出需要经过那些点以及最短距离). 以下图为例: 算法思想 可以使用二维 ...

  7. 蜂窝空间两点最短路径的Python实现

    昨天和Mcree来一场痛快淋漓的头脑风暴​! 叶子为什么是绿色的? 聊起一步步到物理是如何接过生物学家的接力棒深入探索:​参考链接:​为什么植物是绿色的?为了减少光合作用中的噪音 为什么眼睛能看到绿叶 ...

  8. 城市交通导航最短路径查询

    导航最短路径查询系统 上学期期末老师让写一个课程设计,给了很多课题,选了导航最短路径查询系统,题目如下: 1 项目简介 设计一个交通咨询系统,能让旅客咨询从任一个城市顶点到另一个城市顶点之间的最短路径 ...

  9. 如何加快城市路网中最短路径查询效率?

    一.介绍 最短路查询算法是图论中的经典算法,被广泛地应用在不同场景,例如计算机网络中的路由算法.在时空场景下,最短路算法更是支撑了很多应用,例如在路径规划和推荐中最短路是一种最直接的方案,而目前主流的 ...

最新文章

  1. bottle+jquery 前后端分离
  2. 算法与数据结构题目的 PHP 实现:栈和队列 由两个栈组成的队列
  3. springboot yml怎么建常量_Springboot中加载自定义的yml配置文件
  4. Linux 设备驱动开发 —— Tasklets 机制浅析
  5. 微软服务器延迟,经过六个多月的延迟,微软终于推出Hyper-V Server 2019
  6. 浏览器了解(一)浏览器大概流程
  7. “微音乐”微信小程序实战开发过程
  8. PM、PO、PO、PMO、PMP的区别和介绍
  9. phython学习记录 基础篇
  10. 移动端的vm vh是什么
  11. 2.4 深入理解PackageManagerService
  12. SAP 中Table的使用(一、显示数据)
  13. SpringCloud H版之Eureka学习
  14. 洛谷p1307数字反转 c语言
  15. GeoLite2 City库的基本使用与下载, 通过ip查询地址
  16. 如何使用U-Net-train进行语义分段,并在Keras中测试您的自定义数据
  17. Introduction of internet P2P technology
  18. Spring Boot启动器
  19. 2017 黑马 C++ 教学视频
  20. 软件测试-bug详解

热门文章

  1. MySQL批量导入Excel数据【超详细】
  2. IDEA中如何设置键盘快捷键可用
  3. 快捷键使电脑屏幕翻转
  4. C++之适配器(Adapter)模式
  5. jquery创建html标签并添加样式
  6. 云服务器怎么装安卓系统,云服务器怎样装安卓系统
  7. 深度学习(二)-----算法岗面试题
  8. 浅析TSINGSEE智能视频分析网关的AI识别技术及应用场景
  9. 网格平滑基础算法总结
  10. Python+Excel系列:批量处理Excel文件的模块—xlwings:创建、保存、打开工作簿,操控工作表和单元格