from pythonds.graphs import Graph
###BFS采用队列存储待访问顶点
###DFS则是通过递归调用,隐式使用了栈
class DFSGraph(Graph):
def __init__(self):
super().__init__()
self.time = 0
def dfs(self):
for aVertex in self:
aVertex.setColor('white') # 颜色初始化
aVertex.setPred(-1)
for aVertex in self:
if aVertex.getColor() == 'white': # 如果还有未包括的顶点,则建森林
self.dfsvisit(aVertex)
def dfsvisit(self, startVertex):
startVertex.setColor('gray')
self.time += 1 # 算法的步数
startVertex.setDiscovery(self.time)
for nextVertex in startVertex.getConnections():
if nextVertex.getColor() == 'white': # 当前节点是未探索过的
nextVertex.setPred(startVertex) # 就将开始节点设为当前节点的回溯
self.dfsvisit(nextVertex) # 深度优先递归访问
startVertex.setColor('black') # 探索完后,开始节点设为黑色
self.time += 1
startVertex.setFinish(self.time)
拓扑排序
按结束时间倒序
强连通分支
最短路径问题
由u开始,u的邻居x,v,w得到距离d
v,x,w中d最小的是x,先更新x,由x出发更新了v,w,y的d值
v,w,y中d最小的是v,先更新v,这是w的d为2+3=5,比4大,所以w的d=4保持不变
每次更新完的点都会指向他的前驱节点,即最短路径的来源节点
from pythonds.graphs import PriorityQueue,Graph,Vertex
def dijkstra(aGraph,start):
pq = PriorityQueue()
start.setDistance(0) # 开始节点的距离设为0
pq.buildHeap([(v.getDistance(), v) for v in aGraph]) # 对所有顶点建堆,形成优先队列
while not pq.isEmpty():
currentVert = pq.delMin() # 优先队列出队
for nextVert in currentVert.getConnections(): # 遍历当前节点的邻居
newDist = currentVert.getDistance() + currentVert.getWeight(nextVert) # 更新距离
if newDist < nextVert.getDistance(): # 若新的距离值小于之前的距离值,就更新
nextVert.setDistance(newDist) # 更新距离
nextVert.setPred(currentVert) # 设置前驱节点
pq.decreaseKey(nextVert, newDist)
最小生成树
AB,AC,AB的权重小,把B加入到队列中
跟B相连的BC,BD,BE, C和D的权重最小,把C加入
BD,BE,CF中,选择BD,把D加入
from pythonds.graphs import PriorityQueue,Graph,Vertex
import sys
def prim(G, start):
pq = PriorityQueue()
for v in G:
v.setDistance(sys.maxsize)
v.setPred(None)
start.setDistance(0)
pq.buildHeap([(v.getDistance(), v) for v in G])
while not pq.isEmpty():
currentVert = pq.delMin()
for nextVert in currentVert.getConnections():
newCost = currentVert.getWeight(nextVert)
# 若nextVert在pq优先队列里,就不在生成树里,说明是可以安全添加的边
if nextVert in pq and newCost < nextVert.getDistance():
nextVert.setPred(currentVert)
nextVert.setDistance(newCost)
pq.decreaseKey(nextVert, newCost)