今天在图书馆闲逛的时候偶然看见《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)

这样,图的结构和基本操作就完成了。

<Think Complexity> 用字典实现图的更多相关文章

  1. POJ2513(字典树+图的连通性判断)

    //用map映射TLE,字典树就AC了#include"cstdio" #include"set" using namespace std; ; ;//26个小 ...

  2. python数据结构与算法——图的基本实现及迭代器

    本文参考自<复杂性思考>一书的第二章,并给出这一章节里我的习题解答. (这书不到120页纸,要卖50块!!,一开始以为很厚的样子,拿回来一看,尼玛.....代码很少,给点提示,然后让读者自 ...

  3. 图及其衍生算法(Graphs and graph algorithms)

    1. 图的相关概念 树是一种特殊的图,相比树,图更能用来表示现实世界中的的实体,如路线图,网络节点图,课程体系图等,一旦能用图来描述实体,能模拟和解决一些非常复杂的任务.图的相关概念和词汇如下: 顶点 ...

  4. python 集合(set)和字典(dictionary)的用法解析

    Table of Contents generated with DocToc ditctaionary and set hash 介绍 集合-set 创建 操作和访问集合的元素 子集.超集.相对判断 ...

  5. 阿里面试官:HashMap 熟悉吧?好的,那就来聊聊 Redis 字典吧!

    最近,小黑哥的一个朋友出去面试,回来跟小黑哥抱怨,面试官不按套路出牌,直接打乱了他的节奏. 事情是这样的,前面面试问了几个 Java 的相关问题,我朋友回答还不错,接下来面试官就问了一句:看来 Jav ...

  6. Leetcode: Alien Dictionary && Summary: Topological Sort

    There is a new alien language which uses the latin alphabet. However, the order among letters are un ...

  7. 【DG】Oracle_Data_Guard官方直译

    [DG]Oracle Data Guard官方直译 1 Oracle Data Guard 介绍   Oracle Data Guard概念和管理10g版本2   Oracle Data Guard ...

  8. Redis哈希表总结

    本文及后续文章,Redis版本均是v3.2.8 在文章<Redis 数据结构之dict><Redis 数据结构之dict(2)>中,从代码层面做了简单理解.总感觉思路的不够条理 ...

  9. PHP面试(二):程序设计、框架基础知识、算法与数据结构、高并发解决方案类

    一.程序设计 1.设计功能系统——数据表设计.数据表创建语句.连接数据库的方式.编码能力 二.框架基础知识 1.MVC框架基本原理——原理.常见框架.单一入口的工作原理.模板引擎的理解 2.常见框架的 ...

随机推荐

  1. B树在数据库索引中的应用剖析

    引言 关于数据库索引,google一个oracle index,mysql index总 有大量的结果,其中很多的使用方法推荐,**索引之n条经典建议云云.笔者认为,较之借鉴,在搞清楚了自己的需求的基 ...

  2. [转]解决百度统计 gzdecode(): insufficient memory

    百度统计API gzdecode($preLogin->retData, strlen($preLogin->retData)) 这段代码会造成一个PHP警告内存不足,解决办法只要换个解压 ...

  3. JSF 2.0 hello world example

    In this tutorial, we will show you how to develop a JavaServer Faces (JSF) 2.0 hello world example, ...

  4. Spring Autowiring by Constructor

    In Spring, "Autowiring by Constructor" is actually autowiring by Type in constructor argum ...

  5. POJ 3672 Long Distance Racing (模拟)

    题意:给定一串字符,u表示是上坡,d表示下坡,f表示平坦的,每个有不同的花费时间,问你从开始走,最远能走到. 析:直接模拟就好了,没什么可说的,就是记下时间时要记双倍的,因为要返回来的. 代码如下: ...

  6. Activator.CreateInstance 方法 (Type) 的用法

    转自:http://www.cnblogs.com/lmfeng/archive/2012/01/30/2331666.html Activator.CreateInstance 方法 (Type) ...

  7. ie6的兼容问题及解决方案

    1.png24位的图片在ie6浏览器上会出现背景,解决方案是做成png8位: 2.浏览器默认的margin和padding不同,解决方法是用全局重置来统一,即是*{margin:0;padding:0 ...

  8. java web,生成验证码图片的技术

    偶然知道原来有些网站的验证码图片都是随机生成的,后来听人讲了一下,就做了这个小例子 生成图片,绘制背景,数字,干扰线用到了java.awt包,主要使用BufferedImage来生成图片,然后使用Gr ...

  9. 如何将mysql表结构导出成Excel格式的(并带备注)

    http://www.liangchan.net/liangchan/4561.html 1.使用一个mysql管理工具:SQLyog,点击菜单栏“数据库”下拉的最后一项: 导出的格式如下: 2.要想 ...

  10. UOJ #148. 【NOIP2015】跳石头 二分

    #148. [NOIP2015]跳石头 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/148 Descripti ...