python 图遍历

2018-10-03  本文已影响52人  Thinkando
  1. 首先有一个概念:回溯
      回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

代码实现

class Graph:
    class Vertex:
        __slots__='_element'
        def __init__(self,x):
            self._element = x
        def element(self):
            return self._element
        def __hash__(self):
            return hash(id(self))
    class Edge:
        __slots__='_origin','_destination','_element'
        def __init__(self,u,v,x):
            self._origin =u
            self._destination=v
            self._element=x
        def endpoints(self): # 返回元组(u,v)
            return (self._origin,self._destination)
        def opposite(self,v):
            return self._destination if v is self._origin else self._origin
        def element(self):
            return self._element
        def __hash__(self):
            return hash(self._origin,self._destination)
            
    def __init__(self,directed=False):
        self._outgoing = {}
        self._incoming = {} if directed else self._outgoing # 只有在有向图的时候激活
    def is_directed(self):
        return self._incoming is not self._outgoing
    def vertex_count(self):
        return len(self._outgoing)
    def vertices(self):
        return self._outgoing.keys()
    def edge_count(self):
        total = sum(len(self._outgoing[v]) for v in self._outgoing)
        return total if self.is_directed() else total//2 # 有向图边是无向图的两倍
    def edges(self):
        result =set()
        for secondary_map in self._outgoing.values():
            result.update(secondary_map.values) # The A.update(B) adds elements from the set B to A.
        return result
    def get_edge(self,u,v):
        return self._outgoing[u].get(v)
    def degree(self,v,outgoing=True):
        adj = self._outgoing if outgoing else self._incoming
        return len(adj[v])
    def incident_edges(self,v,outgoing=True):
        adj=self._outgoing if outgoing else self._incoming
        for edge in adj[v].values():
            yield edge
    def insert_vertex(self,x=None):
        v=self.Vertex(x)
        self._outgoing[v]={}
        if self.is_directed():
            self._incoming[v]={}
        return v
    def insert_edge(self,u,v,x=None):
        e = self.Edge(u,v,x)
        self._outgoing[u][v]=e
        self._incoming[v][u]=e
# 深度遍历
def DFS(g,u,discovered):
    for e in g.incident_edges(): # for every outgoing edge from u
        v= e.opposite(u)
        if v not in discovered:
            discovered[v]=e
            DFS(g,v,discovered)
# 广度遍历
def BFS(g,s,discovered):
    level=[s]
    while len(level)>0:
        next_level=[]
        for u in level:
            for e in g.incident_edges(u):
                v = e.opposite(u)
                if v not in discovered:
                    discovered[v]=e
                    next_level.append(v)
        level=next_level
上一篇 下一篇

猜你喜欢

热点阅读