用字典实现图

今天在图书馆闲逛的时候偶然看见《Think Complexity》(复杂性思考)这本书,下午看了一会儿觉得很有意思。本书第二章讲的是用Python实现的图,特别写篇博客记录。

 

首先,图有两大元素:顶点和边。分别用Vertex和Edge类来描述顶点集和边集。

 

顶点集:Vertex

class Vertex(object):

    """A Vertex is a node in a graph."""



    def __init__(self, label=''):

        self.label = label



    def __repr__(self):

        """Returns a string representation of this object that can

        be evaluated as a Python expression."""

        return 'Vertex(%s)' % repr(self.label)



    __str__ = __repr__

    """The str and repr forms of this object are the same."""

 

边集:Edge

class Edge(tuple):

    """An Edge is a list of two vertices."""



    def __new__(cls, *vs):

        """The Edge constructor takes two vertices."""

        if len(vs) != 2:

            raise ValueError, 'Edges must connect exactly two vertices.'

        return tuple.__new__(cls, vs)



    def __repr__(self):

        """Return a string representation of this object that can

        be evaluated as a Python expression."""

        return 'Edge(%s, %s)' % (repr(self[0]), repr(self[1]))



    __str__ = __repr__

    """The str and repr forms of this object are the same."""

 

可以看出,边集类实现时继承的是元组,是不可变的对象,其初始化方法重写了__new__()方法。在构造类时,Python会调用__new__()方法创建对象,再调用__init__()方法初始化对象属性,对于可变类型来讲,一般做法是使用默认的__new__()方法,而重写__init__()方法来初始化属性;然而对于不可变类型来说(如元组),__init__()方法不能改变其属性值,因为必须重写__new__()方法来进行初始化。

 

如今图的边和点都有了,现在进行图的构造:

class Graph(dict):

    """A Graph is a dictionary of dictionaries.  The outer

    dictionary maps from a vertex to an inner dictionary.

    The inner dictionary maps from other vertices to edges.

    

    For vertices a and b, graph[a][b] maps

    to the edge that connects a->b, if it exists."""



    def __init__(self, vs=[], es=[]):    #初始化

        """Creates a new graph.  

        vs: list of vertices;

        es: list of edges.

        """

        for v in vs:

            self.add_vertex(v)

            

        for e in es:

            self.add_edge(e)



    def add_vertex(self, v):            #将点添加至图

        """Add a vertex to the graph."""

        self[v] = {}



    def add_edge(self, e):                #添加边,不考虑重边

        """Adds and edge to the graph by adding an entry in both directions.



        If there is already an edge connecting these Vertices, the

        new edge replaces it.

        """

        v, w = e

        self[v][w] = e

        self[w][v] = e



    def get_edge(self, v1, v2):            #返回两点之间的边,若无边返回None

        

        try:

            return self[v1][v2]

        except:

            return None



    def remove_edge(self, e):            #去掉边



        v, w = e

        del self[v][w]

        del self[w][v]



    def vertices(self):                    #返回点集

        

        return [each for each in self]



    def edges(self):                    #返回边集

        edges_list = []

        for each in self.values():

            for each_value in each.values():

                if each_value not in edges_list:

                    edges_list.append(each_value)



        return edges_list



    def out_vertices(self, v):            #返回邻接顶点

        nebor = [each for each in self[v]]

        return nebor

                  

    def out_edges(self, v):                #返回与顶点连接的边

        return [each for each in self[v].values()]

        

    def add_all_edges(self):            #构造完全图

        edges = []

        for v in self:

            for w in self:

                if v != w:

                    e = Edge(v,w)

                    self.add_edge(e)
这样,图的结构和基本操作就完成了。

你可能感兴趣的:(exit)