美文网首页
7.2Graph的实现

7.2Graph的实现

作者: M_小七 | 来源:发表于2019-12-26 14:28 被阅读0次

Python 中,通过字典可以轻松地实现邻接表。我们要创建两个类:Graph 类存储包含所
有顶点的主列表,Vertex 类表示图中的每一个顶点。
Vertex 使用字典 connectedTo 来记录与其相连的顶点,以及每一条边的权重。
addNeighbor 方法添加从一个顶点到另一个的连接。getConnections 方法返
回邻接表中的所有顶点,由 connectedTo 来表示。getWeight 方法返回从当前顶点到以参数
传入的顶点之间的边的权重。

class Vertex:
    def __init__(self, key):
        self.id = key
        self.connectedTo = {}

    def addNeighbor(self, nbr, weight=0):
        self.connevtedTo[nbr] = weight

    def __str__(self):
        return str(self.id) + 'connectedTo:' + str([x.id for x in self.connectedTo])

    def getConnections(self):
        return self.connectedTo.keys()

    def getId(self):
        return self.id

    def getWeight(self, nbr):
        return  self.connectedTo[nbr]


Graph 类中包含一个将顶点名映射到顶点对象的字典。Graph 类也提供了向图中添加顶点和连接不同顶点的方法。getVertices 方法返回图中所有顶点的名字。iter方法,使遍历图中的所有顶点对象更加方便。

class Graph:
    def __init__(self):
        self.vertList = {}
        self.numVertices = 0

    def addVertex(self, key):
        self.numVertices = self.numVertices + 1
        newVertex = Vertex(key)
        self.vertList[key] = newVertex
        return newVertex

    def getVertex(self, n ):
        if n in self.vertList:
            return self.vertList[n]
        else:
            return None

    def __contains__(self, n):
        return n in self.vertList

    def addEdge(self, f, t, cost = 0):
        if f not in self.vertList:
            nv = self.addEdge(f)
        if t not in self.vertList:
            nv = self.addVertex(t)
        self.vertList[f].addNeighbor(self.vertList[t], cost)

    def getVertices(self):
        return self.vertList.keys()

    def __iter__(self):
        return iter(self.vertList.values())


图的应用:词梯问题

词梯Word Ladder问题
由 “ 爱丽丝漫游奇境 ” 的作者 LewisCarroll在1878年所发明的单词游戏
从一个单词演变到另一个单词,其中的过程可以经过多个中间单词。要求是相邻两个单词之间差异只能是1个字母, 如FOOL变SAGE:
FOOL >> POOL >> POLL >> POLE >> PALE >> SALE >> SAGE
目标是找到最短的单词变换序列
采用图来解决这个问题的步骤如下:
将可能的单词之间的演变关系表达为图,采用“广度优先搜索 BFS”,来搜寻从开始单词
到结束单词之间的所有有效路径,选择其中最快到达目标单词的路径

构建单词关系图
❖首先是如何将大量的单词集放到图中
将单词作为顶点的标识Key,如果两个单词之间仅相差1个字母,就在它们之间设一条边
❖从FOOL到SAGE的词梯解,所用的图是无向图,边没有权重
FOOL到SAGE的每条路径都是一个解


image.png

❖单词关系图可以通过不同的算法来构建(以4个字母的单词表为例)
首先是将所有单词作为顶点加入图中,再设法建立顶点之间的边
❖建立边的最直接算法,是对每个顶点(单 词),与其它所有单词进行比较,如果相差仅1个字母,则建立一条边
时间复杂度是O(n^2),对于所有4个字母的5110个单词,需要超过2600万次比较
❖改进的算法是创建大量的桶,每个桶可以存放若干单词
桶标记是去掉1个字母,通配符“_”占空的单词
❖所有匹配标记的单词都放到这个桶里
所有单词就位后,再在同一个桶的单词之间建立边即可


image.png
采用字典建立桶
def buildGraph(file):
    d = {}
    g = Graph()

    #创建词桶
    f = open(file)
    for line in f:
        word = line[:-1]
        # bird
        for i in range(len(word)):
            bucket = word[:i] + '_' + word[i+1:]
            if bucket in d:
                d[bucket].append(word)
            else:
                d[bucket] = [word]
    #构建图
    for bucket in d.keys():
        for v1 in d[bucket]:
            for v2 in d[bucket]:
                if v1 != v2:
                    g.addEdge(v1,v2)
    return g
if __name__ == '__main__':
    g = buildGraph('ds_tree/fourletterwords.txt')
    for item in g.verList.values():
        print(item)

相关文章

  • 7.2Graph的实现

    Python 中,通过字典可以轻松地实现邻接表。我们要创建两个类:Graph 类存储包含所有顶点的主列表,Vert...

  • MD5的几种实现

    PHP的实现 Nodejs的实现 Python的实现 Golang的实现

  • 【call apply bind】源码实现

    call方法的实现 apply方法实现 bind方法实现 new方法实现 reduce实现

  • 基于动态数组的实现 Java实现 基于链表的栈的实现 Java实现

  • 链表

    一、单向链表 单向链表的普通实现 Java实现: Kotlin实现: 单向链表的递归实现 Java实现: 二、双向...

  • JS模拟实现bind,call,apply

    call apply bind 简单实现 函数柯里化的实现 构造函数的实现 ES6实现 结合实现

  • call.apply.bind实现

    call实现 apply实现 bind实现 new实现

  • Java实现最小栈的实现

    栈 实现一个栈,该栈带有出栈(pop)、入栈(push)、取最小元素(getMin)3个方法。要保证这3个方法的时...

  • 单链表 & 双链表& 单向循环链表的实现

    单链表 具体实现: 双链表 代码实现: 单向循环链表的实现 代码实现:

  • 表,栈,队列

    表的实现: ArrayList LinkedList 栈的实现: LinkedStack 队列的实现:

网友评论

      本文标题:7.2Graph的实现

      本文链接:https://www.haomeiwen.com/subject/lxkkoctx.html