今天在图书馆闲逛的时候偶然看见《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. select XXX into 和 Insert into XXX select

    检索一个表中的部分行存到另一张表中. 一 .另外的那张表没有新建的时候,使用 select XXX into,创建的表与原表有相同的列名和类型: select * into Departments_C ...

  2. 给sublime text添加ubuntu launcher快捷方式

    1.下载sublime text 2文件,解压并复制到/opt目录,文件夹名称不要含有空格 2.在/usr/share/applications目录下新建sublime_text.desktop文件 ...

  3. 更换Oracle备份数据文件

    应用背景:需要查看和修改一下Interlib中的数据,所以要反复的将备份数据进行导入和清空.整理一下步骤 删除tablespace drop tablespace interlib including ...

  4. Hadoop学习之--Capaycity Scheduler配置参数说明

    以下列举出来的是capacity关于queue和user资源使用量相关的参数说明: mapred.capacity-scheduler.queue.xxx.capacity: 队列的资源容量百分比,所 ...

  5. Context Menu on DataGrid

    应该设置  fitColumns: true 合并表头显示有问题 代码见示例

  6. homework-02 "最大子数组之和"的问题进阶

    代码编写 这次的作业瞬间难了好多,无论是问题本身的难度或者是单元测试这一原来没接触过的概念或者是命令行参数的处理这些琐碎的问题,都使得这次作业的完成说不上轻松. 最大子数组之和垂直水平相连的拓展问题解 ...

  7. Red5实现直播

    http://pxchen.iteye.com/blog/714591 发布端(Publish): var nc:NetConnection = new NetConnection(); nc.con ...

  8. HDU 4432 Sum of divisors (水题,进制转换)

    题意:给定 n,m,把 n 的所有因数转 m 进制,再把各都平方,求和. 析:按它的要求做就好,注意的是,是因数,不可能有重复的...比如4的因数只有一个2,还有就是输出10进制以上的,要用AB.. ...

  9. lib 和 dll 的区别、生成以及使用详解

    首先介绍一下静态库(静态链接库).动态库(动态链接库)的概念,首先两者都是代码共享的方式. 静态库:在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中,这种库称为静态库,其特点是可 ...

  10. jsp页面显示数据库的数据信息表

    在日常jsp开发中:最基本的一个操作之一是把之前添加到数据库中的信息在jsp页面中显示出来,也就是增删改查中的查找的一部分: 下面是以上部分的开发步骤及分析. 1.在jsp页面: <thead& ...