Graphviz——实现动态更新协议状态机

news2024/10/8 18:22:32

1、描述

  • 为了实现动态更新协议状态机,首先需要定义类来表示协议状态机。初始化该类后,保存状态机对象。在后续更新过程中,就可以加载保存的状态机对象,添加新的状态或事件。
  • Graphviz的安装过程参考:Graphviz——安装、绘制可视化协议状态机(Python)-CSDN博客

2、实现

  • 在fsm.py中首先定义一个协议状态机类。该类保存了节点和边。节点为协议状态,边为触发该状态的事件。
  • 并且还定义了绘制图像、保存状态机,加载状态机的属性。
    • from graphviz import Digraph  # 导入graphviz的Digraph用于绘图
      import pickle  # 导入pickle模块用于序列化和反序列化对象
      
      
      # 定义节点的数据结构
      class Node:
          def __init__(self, code):
              # 初始化节点,设置节点的code
              self.code = code
      
          def __repr__(self):
              # 返回节点的字符串表示
              return f"Node(code={self.code})"
      
      
      # 定义边的数据结构
      class Edge:
          def __init__(self, source, target, event):
              # 初始化边,设置源节点、目标节点和触发事件
              self.source = source
              self.target = target
              self.event = event
      
          def __repr__(self):
              # 返回边的字符串表示
              return f"Edge(source={self.source}, target={self.target}, event={self.event})"
      
      
      # 创建有限状态机
      class FSM:
          def __init__(self):
              # 初始化自定义状态机,创建一个状态机对象并初始化节点和边的存储
              self.fsm = Digraph()  # 使用graphviz的有向图
              self.nodes = {}  # 用于存储节点的字典
              self.edges = []  # 用于存储边的列表
      
          def add_node(self, node):
              # 添加节点到图中
              self.nodes[node.code] = node  # 将节点存储在字典中
              self.fsm.node(node.code)  # 在有向图中添加节点
      
          def add_edge(self, edge):
              # 添加边到图中
              self.edges.append(edge)  # 将边存储在列表中
              self.fsm.edge(edge.source, edge.target, label=edge.event)  # 在有向图中添加边
      
          def __repr__(self):
              # 返回图的字符串表示
              return f"FSM(nodes={self.nodes}, edges={self.edges})"
      
          def draw_graph(self, filename="fsm_graph"):
              # 绘制图
              self.fsm.render(filename, format='png', cleanup=True)  # 渲染图并保存为文件
      
          def save_to_file(self, filename):
              # 保存图到文件
              with open(filename, 'wb') as file:
                  pickle.dump(self, file)  # 使用pickle序列化并保存对象
      
          @staticmethod
          def load_from_file(filename):
              # 从文件加载图
              with open(filename, 'rb') as file:
                  return pickle.load(file)  # 使用pickle反序列化并返回对象
  • 在initialize.py中初始化协议状态机。
    • from fsm import FSM, Edge, Node
      
      if __name__ == "__main__":
          fsm = FSM()  # 创建自定义有向图对象
      
          # 添加节点
          fsm.add_node(Node("220"))  # 添加节点
          fsm.add_node(Node("200"))
          fsm.add_node(Node("331"))
          fsm.add_node(Node("230"))
          fsm.add_node(Node("150"))
          fsm.add_node(Node("226"))
          fsm.add_node(Node("221"))
      
          # 添加边
          fsm.add_edge(Edge("220", "200", "OPTS UTF8 ON"))  # 添加边从节点1到节点2,事件为:OPTS UTF8 ON
          fsm.add_edge(Edge("200", "331", "USER webadmin"))
          fsm.add_edge(Edge("331", "230", "PASS 222"))
          fsm.add_edge(Edge("230", "200", "PORT 192,168,182,1,195,206"))
          fsm.add_edge(Edge("200", "150", "LIST"))
          fsm.add_edge(Edge("150", "226", ""))
          fsm.add_edge(Edge("226", "221", "QUIT"))
      
          # 打印图的表示
          print(fsm)
      
          # 绘制图并保存
          fsm.draw_graph(filename="fsm")
      
          # 保存图到pkl文件
          fsm.save_to_file("fsm.pkl")
    • 运行生成两个文件,fsm.pkl为协议状态机对象文件,fsm.png为协议状态机图。
  • 在load.py中加载保存的协议状态机对象,并更新状态机。
    • from fsm import FSM, Edge, Node
      
      if __name__ == "__main__":
          fsm = FSM.load_from_file("fsm.pkl")
          
          # 添加边
          fsm.add_edge(Edge("200", "221", "QUIT"))
      
          # 打印图的表示
          print(fsm)
      
          # 保存图到pkl文件
          fsm.save_to_file("fsm1.pkl")
      
          # 绘制图并保存
          fsm.draw_graph(filename="fsm1")
    • 运行后,状态机中加入了一条新的边。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1840945.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【AI-6】算力和带宽

上述为大模型训练的显卡选项 tensor fp16 算力是什么? Tensor FP16(Float16)算力是指GPU在执行深度学习的张量计算时,使用float16(半精度浮点)数据类型所能达到的性能指标。 为什么要使用Tensor FP16? 提升计算效率: float16数据类型的存储和计算开销比float32…

htb_Editorial

hack the book Editorial 端口扫描 80 22 目录扫描 /upload 是一个上传book information的页面 其中最顶上有一个可以上传书本封面的地方,可以从本地上传,也可以从远程下载 这里可能涉及ssrf和本地文件上传,逐一尝试 随便上传一个图片…

Redis-五种数据结构之列表(ziplist、quicklist)

列表 文章目录 列表压缩列表-ziplistziplist 定义级联更新 快速列表-quicklistquicklistNode 定义quicklist 定义quicklist常用操作其他操作quicklist 相对于普通链表优点quick应用场景在redis 中使用quicklist 列表数据类型可以存储一组按插入顺序排序的字符串,他很…

web前端-CSS

CSS CSS概述: CSS是Cascading Style Sheets(级联样式表),是一种样式表语言,用于控制网页布局,外观(比如背景图片,图片高度,文本颜色,文本字体,高级定位等等) 可将页面的内容与样式分离开,样式放于单独的.css文件或者HTML某处 CSS是网页样式,HTML是网页…

什么是进程?

目录 进程 进程的特征, 概念 我们下面先简单介绍一下什么是进程 接下来看看一个程序的运行过程 进程的组成 进程的状态和转换 进程的状态 进程状态的转换 ​编辑 进程的组织方式 进程控制 如何实现进程控制 为什么进程控制的过程需要一气呵成? 进程控制的实现…

操作系统入门 -- 进程的同步与互斥

操作系统入门 – 进程的同步与互斥 在之前的文章中,我们了解了进程是如何被调度的。但在调度之前,进程需要获得资源。而获得这些资源则可能让进程之间陷入冲突。为了高效且平等地调度线程,需要引入同步功能。 1.临界资源 1.1 临界资源的描述…

用友YonSuite打通招银云直联,让企业收付款更便利

在当今数智化浪潮席卷全球的背景下,企业对于高效、便捷的管理系统需求日益增加。作为全球领先的企业云服务与软件提供商,用友始终站在技术前沿,致力于为成长型企业提供全方位的数智化解决方案。 用友网络与招商银行通过联通双方系统&#xf…

Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的

文章目录 Elasticsearch聚合查询说明空值率查询DSL Elasticsearch聚合基础知识扩展Elasticsearch聚合概念Script 用法Elasticsearch聚合查询语法指标聚合(Metric Aggregations)桶聚合(Bucket Aggregations)矩阵聚合(Ma…

《昇思25天学习打卡营第1天 | 认识MindScope AI框架和昇思大模型平台》

活动地址:https://xihe.mindspore.cn/events/mindspore-training-camp 昇思MindSpore学习笔记:探索AI的无限可能 嗨,AI爱好者们!今天,我要带你们深入了解一个强大的全场景深度学习框架——昇思MindSpore。 准备好了吗…

信创数据库沙龙 | 全国预告

#数据库沙龙 #国产数据库 #信创数据库

领课教育本地部署教程

一.本地运行环境准备 因node版本需大于18.0所以推荐使用win10及以上系统 1.1MySQL,版本:8.0.x 安装完成导入sql脚本 1.2Redis,版本:3.2,推荐使用最新版本 下载地址:https://github.com/tporadowski/red…

KVB投资安全小知识:如何识别一个货币是避险货币还是风险货币?

摘要 在全球经济不断变化的今天,理解货币的避险属性和风险特征对投资者至关重要。本文将详细探讨如何准确识别一个货币是避险货币还是风险货币,并结合具体的货币案例分析它们的本质差异。通过深入分析不同因素对货币走势的影响,帮助读者在金…

数字孪生技术及其广泛应用场景探讨

通过将实际物理世界中的物体或系统建模、模拟和分析,数字孪生技术可以提供更精确、更可靠、更高效的解决方案。数字孪生技术在智能制造、城市建设、智慧物流等众多领域中得到了广泛的应用。 通过将数据可视化呈现在虚拟环境中,我们可以更清晰地观察和理…

国产数据库中读写分离实现机制

在数据库高可用架构下会存在1主多备的部署,备节点可以根据业务场景分发一部分流量以充分利用资源,并减轻主库的压力,因此在数据库的功能上需要读写分离来实现。 充分利用备节点的资源,提升业务的吞吐量;防止运维等非业…

C++回溯算法(2)

棋盘问题 #include<bits/stdc.h> using namespace std; void func(int,int); bool tf(int,int); void c(); int n,k; char a[110][110]; int cnt20; int main() {cin>>n>>k;for(int i0;i<n;i){for(int j0;j<n;j){cin>>a[i][j];}}func(0,0);cout…

win10远程桌面端口,win10操作系统怎么修改远程桌面端口和共享端口号

在Win10操作系统中&#xff0c;远程桌面端口和共享端口号的修改是两项重要的网络配置任务&#xff0c;它们对于提升系统的安全性和灵活性具有重要意义。以下将分别介绍如何在Win10中修改这两个端口号。 一、Win10操作系统远程桌面端口的修改 远程桌面端口的修改主要涉及到注册…

13.1.资源清单的管理工具-helm

目录 一、helm的介绍 1.helm的价值概述 2.helm的关键名词 二、安装部署helm 1.解压安装包并设置全局命令 2.添加命令补全 三、使用helm部署服务管理 1.使用helm创建chart 1.1创建工作目录 1.2.helm创建chart 2.响应式创建名称空间 3.安装chart到名称空间 4.使用hel…

Unity3D插件开发教程(四):获取地址组件

Unity3D插件开发教程&#xff08;四&#xff09;&#xff1a;获取地址组件 前言 前几天做导出安装包插件时&#xff0c;遇到了个问题&#xff0c;我需要获取地址&#xff0c;可是每次都要手动填入&#xff08;复制粘贴&#xff09;地址是个很费时不讨好的事&#xff0c;所以我…

在 Ubuntu 18.04.4 LTS上安装 netmap

文章目录 步骤运行配置文件编译安装使用netmap 步骤 sudo su sudo apt-get update sudo apt install build-essential sudo apt-get install -y git sudo apt-get install -y linux-headers-$(uname -r)rootVM-20-6-ubuntu:/home/ubuntu/netmap/LINUX# git clone https://gith…

3dmax怎么渲染又快又清晰?

在3ds Max中&#xff0c;追求快速且清晰的渲染效果是每个设计师的目标。云渲染技术的出现&#xff0c;为这一目标提供了强大的支持。通过云渲染&#xff0c;设计师能够利用远程服务器的强大计算能力&#xff0c;实现快速渲染&#xff0c;同时保持图像的高清晰度。 一、3dmax怎么…