【算法——Python实现】无权图(稠密图、稀疏图)及图的遍历

2023-05-16

# _*_ encoding:utf-8 _*_
"""
图
"""

from random import randint
import time
import copy
import Queue


class DenseGraph(object):
    """稠密图 - 邻接矩阵"""
    def __init__(self, n, directed):
        self.n = n  # 图中的点数
        self.m = 0  # 图中的边数
        self.directed = directed  # bool值,表示是否为有向图
        self.g = [[False for _ in range(n)] for _ in range(n)]  # 矩阵初始化都为False的二维矩阵

    def V(self):
        # 返回图中点数
        return self.n

    def E(self):
        # 返回图中边数
        return self.m

    def addEdge(self, v, w):
        # v和w中增加一条边,v和w都是[0,n-1]区间
        if v >= 0 and v < n and w >= 0 and w < n:
            if self.hasEdge(v, w):
                return None
            self.g[v][w] = True
            if not self.directed:
                self.g[w][v] = True
            self.m += 1

    def hasEdge(self, v, w):
        # v和w之间是否有边,v和w都是[0,n-1]区间
        if v >= 0 and v < n and w >= 0 and w < n:
            return self.g[v][w]

    class adjIterator(object):
        """相邻节点迭代器"""
        def __init__(self, graph, v):
            self.G = graph  # 需要遍历的图
            self.v = v  # 遍历v节点相邻的边
            self.index = 0  # 遍历的索引

        def __iter__(self):
            return self

        def next(self):
            while self.index < self.G.V():
                # 当索引小于节点数量时遍历,否则为遍历完成,停止迭代
                if self.G.g[self.v][self.index]:
                    r = self.index
                    self.index += 1
                    return r
                self.index += 1
            raise StopIteration()


class SparseGraph(object):
    """稀疏图- 邻接表"""
    def __init__(self, n, directed):
        self.n = n  # 图中的点数
        self.m = 0  # 图中的边数
        self.directed = directed  # bool值,表示是否为有向图
        self.g = [[] for _ in range(n)]  # 矩阵初始化都为空的二维矩阵

    def V(self):
        # 返回图中点数
        return self.n

    def E(self):
        # 返回图中边数
        return self.m

    def addEdge(self, v, w):
        # v和w中增加一条边,v和w都是[0,n-1]区间
        if v >= 0 and v < n and w >= 0 and w < n:
            # 考虑到平行边会让时间复杂度变为最差为O(n)
            # if self.hasEdge(v, w):
            #   return None
            self.g[v].append(w)
            if v != w and not self.directed:
                self.g[w].append(v)
            self.m += 1

    def hasEdge(self, v, w):
        # v和w之间是否有边,v和w都是[0,n-1]区间
        # 时间复杂度最差为O(n)
        if v >= 0 and v < n and w >= 0 and w < n:
            # for i in self.g[v]:
            #   if i == w:
            #       return True
            # return False
            if w in self.g[v]:
                return True
            else:
                return False

    class adjIterator(object):
        """相邻节点迭代器"""
        def __init__(self, graph, v):
            self.G = graph  # 需要遍历的图
            self.v = v  # 遍历v节点相邻的边
            self.index = 0  # 遍历的索引

        def __iter__(self):
            return self

        def next(self):
            if len(self.G.g[self.v]):
                # v有相邻节点才遍历
                if self.index < len(self.G.g[self.v]):
                    r = self.G.g[self.v][self.index]
                    self.index += 1
                    return r
                else:
                    raise StopIteration()
            else:
                raise StopIteration()


class ReadGraph(object):
    """读取文件中的图"""
    def __init__(self, graph, filename):
        with open(filename, 'r') as f:
            line = f.readline()
            v, e = self.stringstream(line)
            if v == graph.V():
                lines = f.readlines()
                for i in lines:
                    a,b = self.stringstream(i)
                    if a >= 0 and a < v and b >=0 and b < v:
                        graph.addEdge(a, b)

    def stringstream(self, text):
        result = text.strip('\n')
        result = result.split()
        a, b = result
        return int(a), int(b)


class Component(object):
    """深度优先遍历和联通分量"""
    def __init__(self, graph):
        self.G = graph  # 图
        self.ccount = 0  # 联通分量
        self.visited = [False for _ in range(self.G.V())]  # 记录每个节点是否被遍历
        self.id = [-1 for _ in range(self.G.V())]  # 相连节点的id相同,初始都为-1
        i = 0
        while i < self.G.V():
            if not self.visited[i]:
                self.dfs(i)
                self.ccount += 1
            i += 1

    def dfs(self, v):
        # 深度优先遍历
        self.visited[v] = True
        self.id[v] = self.ccount
        adj = self.G.adjIterator(self.G, v)  # 找到v节点所有相邻的点,进行迭代遍历
        for i in adj:
            # 如果遍历到还未遍历的节点,继续向下进行递归的深度遍历
            if not self.visited[i]:
                self.dfs(i)

    def count(self):
        # 返回联通分量
        return self.ccount

    def isConnected(self, v, w):
        # 判断节点是否相连
        if v >=0 and v < self.G.V() and w >= 0 and w < self.G.V():
            return self.id[v] == self.id[w]


class Path(object):
    """寻找路径"""
    def __init__(self, graph, s):
        self.G = graph  # 图
        self.s = s  # 从s节点开始寻找到其他节点的路径
        self.visited = [False for _ in range(self.G.V())]  # 记录每个节点是否被遍历
        self.fromed = [-1 for _ in range(self.G.V())] # 记录此节点来自哪个节点的连接

        # 寻找路径
        self.dfs(s)

    def dfs(self, v):
        # 深度优先遍历
        self.visited[v] = True
        adj = self.G.adjIterator(self.G, v)  # 找到v节点所有相邻的点,进行迭代遍历
        for i in adj:
            # 如果遍历到还未遍历的节点,继续向下进行递归的深度遍历
            if not self.visited[i]:
                self.fromed[i] = v  # 对还未遍历的节点,先将此节点的from修改为v,表示i节点来自v节点相连
                self.dfs(i)

    def hasPath(self, w):
        # w与v是否有路径
        if w >= 0 and w < self.G.V():
            return self.visited[w]

    def path(self, w):
        # 从v到w的路径
        s = []
        p = w
        while p != -1:
            s.append(p)
            p = self.fromed[p]
        s.reverse()
        return s

    def showPath(self, w):
        # 展示路径
        s = self.path(w)
        for i in s:
            print i


class ShortestPath(object):
    """广度优先遍历和最短路径"""
    def __init__(self, graph, s):
        self.G = graph  # 图
        self.s = s  # 从s节点开始寻找到其他节点的路径
        self.visited = [False for _ in range(self.G.V())]  # 记录每个节点是否被插入队列
        self.fromed = [-1 for _ in range(self.G.V())] # 记录此节点来自哪个节点的连接
        self.ord = [-1 for _ in range(self.G.V())]  # 记录s节点到每一个节点的距离
        # 无向图最短路径算法
        q = Queue.Queue()
        q.put(s)
        self.visited[s] = True
        self.ord[s] = 0
        while not q.empty():
            v = q.get()
            adj = self.G.adjIterator(self.G, v)  # 找到v节点所有相邻的点,进行迭代遍历
            for i in adj:
                # 如果遍历到还未加入过队列的节点,将其加入队列
                if not self.visited[i]:
                    q.put(i)
                    self.visited[i] = True
                    self.fromed[i] = v
                    self.ord[i] = self.ord[v] + 1

    def hasPath(self, w):
        # w与v是否有路径
        if w >= 0 and w < self.G.V():
            return self.visited[w]

    def path(self, w):
        # 从v到w的路径
        s = []
        p = w
        while p != -1:
            s.append(p)
            p = self.fromed[p]
        s.reverse()
        return s

    def showPath(self, w):
        # 展示路径
        s = self.path(w)
        for i in s:
            print i

    def length(self, w):
        # s到w的距离
        if w >= 0 and w < self.G.V():
            return self.ord[w]

if __name__=="__main__":
    n = 13
    g1 = DenseGraph(n, False)
    # for _ in range(100):
    #   a = randint(0,n-1)
    #   b = randint(0,n-1)
    #   g1.addEdge(a, b)
    # v = 0
    # adj = DenseGraph.adjIterator(g1, v)
    # for w in adj:
    #   print w
    filename = 'graph.txt'
    readgraph1 = ReadGraph(g1, filename)
    # component1 = Component(g1)
    # print component1.count()
    path1 = Path(g1, 0)
    print path1.path(8)
    path1.showPath(8)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【算法——Python实现】无权图(稠密图、稀疏图)及图的遍历 的相关文章

  • 一些截图

  • 基于busybox的bootchart分析

    一 Bootchart简介 Bootchart官网http www bootchart org xff0c 已经很久没有更新了 Bootchart的目的是将启动阶段的性能可视化 xff08 Boot Process Performance
  • 用Android手机spydroid-ipcamera搭载局域网监控环境

    相比有很多人都想用手机实现视频监控吧 xff0c 今天这个教程 xff0c 将会教大家用spydroid ipcamera搭建局域网监控环境 准备工作 xff1a 1 准备一部带有摄像头的 xff0c API level在9以上的手机 xf
  • 3D数学--学习笔记(三):3D中绕任意轴的旋转

    本文转自 xff1a http blog csdn net zjc game coder article details 24269757 不要小看我们在Unity或者3DMAX中的一个简单的旋转物体操作 题记 这里需要用到的知识 xff1
  • Android拼图游戏开发全纪录0

    本文转自 xff1a http blog csdn net eclipsexys article details 18881849 最近刚完成一个Android的小项目 拼图游戏 项目并不复杂 xff0c 但也是一个完整的项目 xff0c
  • Android拼图游戏开发全纪录1

    本文转自 xff1a http blog csdn net eclipsexys article details 18887567 今天我们继续来讲解Android拼图游戏全纪录的第二篇 xff0c 今天要完成的任务比较简单 xff1a 界
  • Android 4.2 SafeVolume机制

    最近一个项目过认证 xff0c 在声压测试时failed 整改方案为 xff1a 在用户将耳机音量提高至安全音量以上时 xff0c 阻止此操作并弹出警告框 xff0c 待用户确认后才提升音量 一开始并不知道android4 2中默认自带了这
  • MarkDown基础语法

    MarkDown基础语法 什么是MarkDown Markdown是一种轻量级标记语言 xff0c 创始人为约翰 格鲁伯 xff08 英语 xff1a John Gruber xff09 允许人们使用易读易写的纯文本格式编写文档 xff0c
  • 命令行查看android手机wi-fi密码

    两招帮你查看wifi密码 xff08 抱歉 xff1a 由于无法传第三张图片 xff0c 第三个图片内容请参照参考网址获得 xff09 第一 xff0c 手机必须root 第二 xff0c 用es文件浏览器或RE管理器进入date misc
  • android网络时间同步总结

    本文转自 xff1a http www cnblogs com hoji real archive 2011 11 14 2247984 html 最近看了下网络时间同步 xff0c 总结一下 整体描述 xff1a android网络时间同
  • win7删除ubuntu系统

    win7 43 ubuntu双系统 xff0c ubuntu开机的时候 xff0c 电脑会响 xff0c ubuntu系统进不去 进入win7系统后 xff0c F盘是通过磁盘管理压缩剩余空间安装ubuntu系统的 xff0c QQ安装在F
  • 手机电池和taskId的寻找

    刷机的时候启动手机时间比较久 xff0c 拔掉电池给手机断电 xff0c 启动的比较快一点 一直这样干 xff0c 一段时间以后 xff0c 手机充电的时候 xff0c 会显示bad battery 提示电池坏掉 电池坏掉后 xff0c 刷
  • Objective-c的内存管理MRC与ARC

    Objective c中提供了两种内存管理机制MRC xff08 MannulReference Counting xff09 和ARC Automatic Reference Counting xff0c 分别提供对内存的手动和自动管理
  • 修复:connectToBus() Connection Error(Using X11 for dbus-daemon autolaunch was disabled at compile time

    1 问题 xff1a d bus 在 dbus daemon 没有运行起来的环境中会报这个错 xff1a connectToBus Connection Error Using X11 for dbus daemon autolaunch
  • Git 初体验

    文章目录 1 文章结构2 Git安装3 个人开发3 1 怎么理解SSH xff1f 3 2 SSH场景3 2 1 场景13 2 2 场景23 2 3 场景3 3 3 怎么理解HTTPS xff1f 4 公司开发5 小二总结 上篇文章 xff
  • 一年一度的1024,一周一次的每周思考,来点碰撞

    时间过得真快呀 xff0c 又到了著名的 程序员节 最近在整理任务的时候 xff0c 发现列表中还藏着这样一条 在科技日益发达的今天 xff0c 恰逢 程序员节 xff0c 小二不免又产生了一些思考 前几年 xff0c 老家附近修了飞机场
  • 鲲鹏HCIA系列笔记题库汇总(内含PDF)

    大家好呀 xff0c 我是小二 xff0c 好久不见 之前小二分享了几篇鲲鹏 HCIA 认证的笔记 xff0c 反响还不错 现在小二特地把几篇笔记整理成一个 PDF 文档 xff0c 方便阅读 xff0c 也方便查找 目前已经更新到 V1
  • 【每周思考-15】我是标题

    不知道写什么 xff0c 先陈述一些事实吧 C程序设计语言 本周终于看完了第一遍 xff0c 练习题正在进行 从零开始学理财 杨婧 也看完了 xff0c 实操也在慢慢进行 xff0c 周期久一点 x1f611 上周末看了 金陵十三钗 xff
  • javaweb中jstl无法解析的错误解决方法

    javaweb中jstl无法解析的错误解决方法 无法在web xml或使用此应用程序部署的jar文件中解析绝对uri xff1a http java sun com jstl core 一 问题的产生 在javaweb项目中引入了 jstl
  • 500、1000

    上周日 xff0c 是我参加工作整整 1000 天 xff0c 确实没想到 xff0c 我都已经混迹职场这么久了 周一呢 xff0c 也是距离我写第一篇公众号文章的第 500 天 xff0c 确实也没想到写这么久了 两个相比较来说 xff0

随机推荐

  • 说实话,想家了

    想家了 这周最大的惊喜 xff0c 就是发现1月底该过年了 xff0c 好开心啊 xff01 毕业这几年是越来越恋家 xff0c 光是想想跟家人在一块的时光 xff0c 就美滋滋的 也许是这几年发生了太多事情 xff0c 前年爸爸车祸 xf
  • 恭喜“结业”啦

    之前报名的深圳市人工智能培训 xff0c 今天上完了最后一次课 xff0c 也考完试 xff0c 拿到结业证书啦 xff0c 哈哈 这个课程是人社局主办的 xff0c 有市级 区级的培训 个人觉得挺好 xff0c 带我简单的了解下人工智能的
  • 思考,分享

    不知不觉 xff0c 每周思考也陪我跨了个年 xff0c 本篇已经是第 22 周了 写 每周思考 时 xff0c 总能让我回想起很多事情 近段时间 xff0c 大部分精力都扑在工作上了 xff0c 工作日晚上回家 xff0c 也没有写文章的
  • Git代码提交,固定日志模板

    时间 xff1a 2022年1月9日21 38 22 团队开发 xff0c 但是每个人的日志风格不同该怎么办 xff1f 通过配置服务器的 Git 提交日志 xff0c 就可以实现统一的代码提交风格 先看实现效果 xff0c 如下图 这样大
  • 《伤逝——涓生的手记》,读后有感

    看鲁迅先生的 狂人日记 有一段时间了 xff0c 其中有一短篇 xff0c 名叫 伤逝 涓生的手记 xff0c 有一些浅显的思考 xff0c 分享给大家 xff0c 可以互相讨论学习 x1f37b 参考资料 xff1a 百度百科 伤逝 xf
  • 我的2021

    牛年的事情 xff0c 肯定要在牛年结束 现在已经是 2022 年的一月份了 xff0c 才开始动笔 xff0c 写这份 2021 的年终总结 有两方面的原因 xff0c 一方面是觉得 12 月的时间太紧了 xff08 参加了培训班 xff
  • C/C++ 语言 printf 可以直接使用宏定义打印?

    hello xff0c 你好呀 xff0c 我是小二 在 编码 过程中 xff0c 小二发现一种神奇的用法 xff1a 打印时 xff0c 直接使用宏定义 xff01 于是小二决定自己尝试一把 1 基础环境 使用的在线编译器是这个 x1f4
  • Anaconda3安装教程记录

    参考资料 1 官网 xff1a https www anaconda com products individual 2 安装教程 xff1a https mp weixin qq com s ip8TQF2pyjLwEBixwoxxBw
  • Anaconda3修改默认环境保存路径

    参考链接 1 https blog csdn net javastart article details 102563461 配置方法 方法一 1 修改 C 盘 condarc 隐藏文件 xff1b 2 在文件末尾增加如下内容 envs d
  • javaweb servlet 在控制台上输出乱码的解决

    上午打开我的idea 正在愉快的写代码 xff0c 某段程序中需要servlet在控制台上打印一个消息 xff0c 一个悲催的故事发生了 xff0c 打印的中文字符全乱码了 难道是我的tomcat xff0c 没有设置吗 xff1f tom
  • Win10系统,使用VSCode提示错误fatal: detected dubious ownership in repository at

    1 环境信息 1 Win10 系统 2 VSCode 软件 2 问题现象 使用 VSCode 打开 Samba 中的 Git 工程时 xff0c Git 相关插件不会启用 xff0c 通过 git 输出界面 xff0c 可以看到有提示如下错
  • C++程序存在多个cin输入时,后边的cin失效

    1 参考资料 1 https www cnblogs com pengjun shanghai p 4800871 html 2 C 43 43 Primer Plus xff08 第6版 xff09 中文版 xff0c 第 4 2 5 小
  • C++整形变量临界值问题思考

    最近调试代码时 xff0c 遇到了一个问题 程序中定义了 int 类型的变量 xff0c 在代码中做自增操作 xff0c 当达到某一阈值 xff08 等于15 xff09 的时候 xff0c 会做一些特殊处理 实际测试发现 xff0c 该阈
  • Windows与Linux行尾换行符引发Git的一系列惨案

    1 前言 最近在使用 Git 提交代码的时候 xff0c 老是碰到一段看起来 没有任何改动 的代码 xff0c 被 diff 检测出异常 xff0c 很是苦恼 xff0c 特别是项目紧急的时候 xff0c 不敢用 VSCode 编辑了 xf
  • 防止C++程序重复运行的几种方法

    防止C 43 43 程序重复运行的几种方法 有时候 xff0c 为了某些要求 xff0c 我们希望程序实例只运行一次 而在VB6中 xff0c 我们可以很轻易的根据App hPreInstance来判断程序是否已经运行 但是在C 43 43
  • 玩转 ESP32 + Arduino(二十八) TFT_eSPI库驱动ST7789

    我们用到的库 TFT eSPI 一 硬件接线 这里我们使用了中景园的ST7789 一般屏幕的引脚定义如下 接线 我们直接用VSPI接线 ESP32引脚ST7789引脚功能GNDGND接地3V3VCC电源 VCLK 18SCLSPI时钟线 V
  • Golang学习篇——UTC时间互换标准时间

    Golang时间相关处理 xff0c 相关包 34 time 34 1 UTC时间转标准时间 UTC时间转标准时间 func this DataSearch UTCTransLocal utcTime string string t 61
  • 解决libgtk2.0-dev依赖包的问题

    依赖 libtotem plparser dev gt 61 3 4 但是它将不会被安装 依赖 valac gt 61 0 20 但是它将不会被安装 依赖 libvte 2 90 dev gt 61 1 0 32 但是它将不会被安装 E 无
  • SLF4JLoggerContext cannot be cast to LoggerContext

    org apache logging slf4j SLF4JLoggerContext cannot be cast to org apache logging LoggerContext hive启动时 一直报错 原因是 hadoop与h
  • 【算法——Python实现】无权图(稠密图、稀疏图)及图的遍历

    span class hljs comment encoding utf 8 span span class hljs string 34 34 34 图 34 34 34 span span class hljs keyword from