通用的圖的深度優先算法代碼實現(使用Python實現)


問題背景

關於圖和深度優先的相關資料網上已經有很多了.本文側重於如何代碼實現.

深度優先涉及到遞歸算法.需要事先理解遞歸的運行邏輯(以下代碼使用遞歸實現深度優先).

圖釋

代碼

  • 下面的Vertex 與 Graph 是圖的結構邏輯實現.但是很多屬性和方法是沒有用到的. Vertex表示的是單個點,Graph存儲的是圖.
import sys
class Vertex: # 點
    def __init__(self,num):
        self.id = num
        self.connectedTo = {}
        self.color = 'white'
        self.dist = sys.maxsize
        self.pred = None # pred 表示前驅節點
        self.disc = 0
        self.fin = 0

    # def __lt__(self,o):
    #     return self.id < o.id
    
    def addNeighbor(self,nbr,weight=0): # 添加鄰接邊
        self.connectedTo[nbr] = weight
        
    def setColor(self,color): # 設置顏色
        self.color = color
        
    def setDistance(self,d):
        self.dist = d

    def setPred(self,p): # 設置前驅節點
        self.pred = p

    def setDiscovery(self,dtime):
        self.disc = dtime
        
    def setFinish(self,ftime):
        self.fin = ftime
        
    def getFinish(self):
        return self.fin
        
    def getDiscovery(self): # 設置發現時間
        return self.disc
        
    def getPred(self): # 獲得前驅節點
        return self.pred
        
    def getDistance(self):
        return self.dist
        
    def getColor(self): # 設置顏色
        return self.color
    
    def getConnections(self):
        return self.connectedTo.keys()
        
    def getWeight(self,nbr):
        return self.connectedTo[nbr]
                
    def __str__(self):
        return str(self.id) + ":color " + self.color + ":disc " + str(self.disc) + ":fin " + str(self.fin) + ":dist " + str(self.dist) + ":pred \n\t[" + str(self.pred)+ "]\n"
    
    def getId(self):
        return self.id

class Graph: # 圖
    def __init__(self):
        self.vertices = {}
        self.numVertices = 0
        
    def addVertex(self,key): # 添加邊
        self.numVertices = self.numVertices + 1
        newVertex = Vertex(key)
        self.vertices[key] = newVertex
        return newVertex
    
    def getVertex(self,n): # 是否擁有此點
        if n in self.vertices:
            return self.vertices[n]
        else:
            return None

    def __contains__(self,n):
        return n in self.vertices
    
    def addEdge(self,f,t,cost=0): # 添加邊 (如果此前沒有節點,則會添加節點)
            if f not in self.vertices:
                nv = self.addVertex(f)
            if t not in self.vertices:
                nv = self.addVertex(t)
            self.vertices[f].addNeighbor(self.vertices[t],cost)
    
    def getVertices(self):
        return list(self.vertices.keys())
        
    def __iter__(self):
        return iter(self.vertices.values())
  

  • 下面的類實現了圖的深度優先搜索.
class DFSGraph(Graph): # 繼承其類
    def __init__(self):
        super().__init__() # 繼承了其方法
        self.time = 0

    def dfs(self): # 深度優先
        # self指向的是類的實例化
        for aVertex in self: # self => 其有鄰接矩陣的值 / 也就是邊
            # print(self)
            aVertex.setColor('white') # 顏色初始化
            aVertex.setPred(-1)

        for aVertex in self: # 如果還有未包括的頂點,則建立森林
            if aVertex.getColor() == 'white':
                # print(aVertex.id) # A
                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)





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM