用python做DEVS离散事件建模与仿真

2023-11-07

1 DEVS --离散事件运行规范

离散事件系统规范 DEVS( discrete event system specification)是由美国学者 B. P. Zeigler等提出的一种模块化建模方法 ,它将描述对象中的每个子系统看作一个具有内部独立结构和输入输出接口 的模块,具有规范化、层次化、模块化的建模优势。
DEVS是一种离散事件运行规范,专门用于处理离散事件的仿真,例如大学学过的狼羊农夫过河问题、元胞自动机问题等,都可以划分到这个范围里。
DEVS不是一门语言,更像是一种带有完整理论和仿真执行机制的建模思想,编程语言是其实现的载体。这一点有些像Torch这个深度学习框架,重要的是这一套前向反向传播的机制流程和思路,而不是基于python还是c++实现Torch架构。
DEVS包含模型、仿真器、实验框架三个部分,和建模过程最相关的就是模型。模型分为原子模型和耦合模型,耦合模型是原子模型之间互相连接得到的。
最重要的原子模型的定义为 :

M = < X , S , Y , δ i n t , δ e x t , λ , t a > M = <X, S,Y,\delta_{int},\delta_{ext},\lambda,t_a> M=<X,S,Y,δint,δext,λ,ta>

其中 X 是外部输入集 , S是系统的序列状态集 , Y是外部输出集 ; δ i n t \delta_{int} δint 是内部转移函数 , 它描述内部事件发生所引起的系统状态变化 ; δ e x t \delta_{ext} δext是外部转移函数 , 描述的是外部事件引起的系统状态变化; λ \lambda λ是输出函数 , 它为输出端产生外部事件: t a t_a ta是时间推进函数,用于产生每一个状态的持续时间。
DEVS为描述模型提供了一种严格的规范 ,它为建立模型的边界层次和抽象模型之间的依赖关系提供了一 种方法。 因而 , 能够很方便的描述智能体的决策和适应过程 , 以及它们之间的交互 。

2 python下安装devs包

python的官网有一个名为devs 0.1.8的包,并且说只需要pip就可以安装。但是实际上这个包已经很久没有更新过了,基本上安装的时候会出很多的问题,所以不建议使用官网的devs包。
github上有一些python的devs包,都是国外各个大学或者研究机构的仿真大佬们开发的,在这里推荐一个非常好用的库:pythonPDEVS
如果下载不下来的话,可以使用网盘资源(提取码:kyrq)
将整个文件夹下载下来后,找到里面的src文件夹,在当前路径下打开CMD命令行窗口,输入:

python setup.py install --user

安装完成后,打开一个python脚本文件,输入:

import pypdevs

如果import成功代表安装完成。

3 pypdevs包的宏观解读

pypdevs库的全部说明在官方文档里写的比较清晰。
总的来说: 作为一个基于面向对象架构的DEVS包,pypdevs有三个最主要的子类,分别是pypdevs.DEVS.AtomicDEVS、pypdevs.DEVS.CoupledDEVS以及pypdevs.simulator.Simulator,分别对应于原子模型、耦合模型以及仿真器。
使用方法: 主要通过继承关系来重写父类方法,实现DEVS框架的搭建,与使用pytorch搭建神经网络模型时对forward函数的重写方式类似。

原子模型AtomicDEVS的常用方法

extTransition: 外部事件转移函数,返回self.state
intTransition:内部事件转移函数,返回self.state
confTransition:确认转移函数,返回self.state
outputFnc:输出函数,返回一个字典
timeAdvance:时间步长ta,返回一个数值或者无穷
Finalize: 确认最后的状态

耦合模型CoupledDEVS的常用方法

select: 选择函数
getModelLoad:获得耦合模型的原子模型数量
finalize:仿真前确认最后的状态
flattenConnections:对每一个原子模型端口操作
unflattenConnections:对每一个原子模型进行端口操作
addSubModel:增加子模型
removeSubModel:移除子模型
disconnectPorts:将两个端口解耦
connectPorts:将两个端口连接起来

仿真器Simulator的使用方法

在搭建完原子模型和耦合模型之后,将其添加入DEVS仿真器即可运行:

model = Couplemodel()  # 实例化耦合模型
sim = Simulator(model)  # 加入到仿真器中
sim.setVerbose(None)  # 打印离散事件
sim.setClassicDEVS()  # 使用经典(串行)的DEVS
sim.setTerminationTime(20)  # 设置仿真运行的总时间
sim.simulate()  # 开始仿真

4 pypdevs仿真实例

使用一个grid-world为背景的简单智能体模型来进行示例:
模型简介: 1、智能体在二维环境中可以感知到自己上下左右一个间隔的距离,在grid-world中设置两种障碍物。2、一种障碍物在被看到后智能体会靠进去待一个时间步长、另一种障碍物智能体在看到他时会远离它,墙壁属于第二种障碍物。3、智能体完全遵循随机行走,完全随机选择四个方向,但是会尽可能地不走重复的路。
模型结构:
Walker向Env环境发送自己的位置(state),Env向Walker发送其下一步可以走的位置,以及其上下左右四个可感知范围内是否存在障碍物的相关信息。
在这里插入图片描述
程序:

from pypdevs.DEVS import *
from pypdevs.infinity import INFINITY
from pypdevs.simulator import Simulator
import random
# 步骤:
# 1 原子模型
# 2 耦合模型
# 3 加入仿真器

# 1-搭建原子模型
class Walker(AtomicDEVS):
    def __init__(self):
        AtomicDEVS.__init__(self, "Walker")
        self.state = (0,0)  # 起始状态
        self.time_step = 1.0  # 时间步长都取1
        self.outport = self.addOutPort("outport")  # 增加端口
        self.inport = self.addInPort("inport")  # 增加端口
        self.isbegin = False
        self.visited = []
        
    def timeAdvance(self):  # ta 要的是返回值
            return self.time_step
            
    # 输出
    def outputFnc(self):  # ta 要的是返回值
        # Our message is simply the integer 5, though this could be anything
        print(self.state)
        return {self.outport: self.state}

    def intTransition(self):  # ta 要的是返回值
        self.visited.append(self.state)
        with open("state.txt", "a", encoding="utf-8") as f:
            print(self.state, file=f)
        return self.state

    # 外部事件转移函数
    def extTransition(self, inputs):
        self.isbegin = True
        self.possible_states_dict = inputs[self.inport]  # 找到inputs里的对应的字典端口,必是字典格式
        # print(self.possible_states_dict)
        # print("agt:", 666)
        self.ways = self.possible_states_dict["ways"]
        self.target1 = self.possible_states_dict["target1"]
        self.target2 = self.possible_states_dict["target2"]
        # 得到了[(),(),(),()], [()],[()]
        temp = []
        for eve in self.ways:
            if eve not in self.target2:
                temp.append(eve)
        is_no_way = True
        for eve in temp:
            if eve not in self.visited:
                is_no_way = False
        if not is_no_way:
            for eve in self.visited:
                if eve in self.target1:
                    self.target1.remove(eve)
                if eve in self.ways:
                    self.ways.remove(eve)
        if len(self.target1) > 0:
            self.state = self.target1[random.randint(0, len(self.target1) - 1)]
            return self.state
        if len(self.target2) > 0:
            temp = []
            for eve in self.ways:
                if eve not in self.target2:
                    temp.append(eve)
            self.ways = [eve for eve in temp]
            self.state = self.ways[random.randint(0, len(self.ways)-1)]
            return self.state
        self.state = self.ways[random.randint(0, len(self.ways) - 1)]
        return self.state

# 搭建原子模型
class Gridworld(AtomicDEVS):
    def __init__(self):
        AtomicDEVS.__init__(self, "Gridworld")
        self.state = {}
        self.env = [
          [0, 0, 0, 0, 0],
          [0, 1, 0, 0, 0],
          [0, 0, 0, -1, 0],
          [0, 0, 1, 0, 0],
          [0, 0, 0, 0, 0]
        ]  # 5*5
        self.env_size = 5
        tmp = [[(i,j) for i in range(self.env_size)] for j in range(self.env_size)]
        self.all_state = []
        for eve in tmp:
          for ev in eve:
              self.all_state.append(ev)
        self.time_step = 1.0  # 时间步长都取1
        self.inport = self.addInPort("input")
        self.outport = self.addOutPort("output")
        self.isbegin = False

    def timeAdvance(self):
        if self.isbegin:
            return self.time_step
        else:
            return INFINITY

    def outputFnc(self):
        return {self.outport: self.state}

    def extTransition(self, inputs):
        agt_state = inputs[self.inport]  # 找到inputs里的对应的字典端口,必是字典格式
        self.isbegin = True
        tmp = [
            (agt_state[0]+1, agt_state[1]),
            (agt_state[0]-1, agt_state[1]),
            (agt_state[0], agt_state[1]+1),
            (agt_state[0], agt_state[1]-1)
        ]
        ways = []
        target1 = []
        target2 = []
        for eve in tmp:
            if eve in self.all_state:
                ways.append(eve)

                if self.env[eve[0]][eve[1]] == 1:
                    target1.append(eve)
                if self.env[eve[0]][eve[1]] == -1:
                    target2.append(eve)
        self.state["ways"] = ways
        self.state["target1"] = target1
        self.state["target2"] = target2
        return self.state

    def intTransition(self):
        self.isbegin = False
        return self.state


# 搭建耦合模型
class CQueue(CoupledDEVS):
    def __init__(self):
        CoupledDEVS.__init__(self, "CQueue")
        self.walker = self.addSubModel(Walker())
        self.gridworld = self.addSubModel(Gridworld())
        self.connectPorts(self.walker.outport, self.gridworld.inport)
        self.connectPorts(self.gridworld.outport, self.walker.inport)

# 进行仿真
model = CQueue()
sim = Simulator(model)
sim.setVerbose(None)
sim.setClassicDEVS()
sim.setTerminationTime(20)
sim.simulate()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用python做DEVS离散事件建模与仿真 的相关文章

  • GBN,SR,TCP区别

    GBN 回退N go back N 如果某个报文段没有被正确的接收 那么从这个报文段到后面的报文段都要重新发送 返回的ACK采用剋及确认的机制 也就是说如果GBN返回的ACK 3 也就是说3报文段和3 之前的报文段都被正确地接收了 SR 接
  • 基于Vue3实现鼠标按下某个元素进行拖动,实时改变左侧或右侧元素的宽度,以及点击收起或展开的功能

    前言 其原理主要是利用JavaScript中的鼠标事件来控制CSS样式 大致就是监听某个DOM元素的鼠标按下事件 以及按下之后的移动事件和松开事件 在鼠标按下且移动过程中 可实时获得鼠标的X轴坐标的值 通过简单计算 可计算出目标元素的宽度
  • uboot-链接脚本(u-boot.lds)

    学习目标 uboot链接脚本分析 学习内容 学习使用了正点原子的I MX6ULL教程及开发平台 uboot的链接脚本u boot lds u boot map 学习时间 2022 07 17 学习产出 分析uboot的启动流程之前 首先要找
  • npm install 报错 ERR! network ‘proxy‘ config is set properly. See: ‘npm help config‘

    想用npm创建项目 但是突然报了个问题 问题 使用 npm install 初始化项目依赖失败 报错 proxy config is set properly See npm help config npm WARN registry Un
  • 多行同时编辑(idea)

    同时按住 Ctrl Shift Alt 点击要编辑的地方就可以同时编辑了
  • stm32图像识别分类技术,陈老师简单为你阐述一下

    STM32图像分类 前言 可能有的同学会有疑问 STM32 能做图像分类这么复杂的事情吗 嵌入式系统中视觉技术的迅速普及 推动了用于汽车安全 机器视觉和运动分析的超高速成像攻克方案 相应地 通过更壮大的图像传感器和更小的像素体系构造 能够显
  • 学习Java面向对象编程和设计模式最好的5本书

    对于任何一个Java开发人员来说 必须学会面向对象的设计原则和各种设计模式的知识 但有一些关于面向对象设计原则 设计模式和最佳实践的书籍 只有少数几本书能做到真正在讲解这方面内容 设计原则和设计模式 设计原则是基础 设计模式是基于这个基础的
  • OAuth2.0 授权模式,基于HttpClient 实现

    功能代码如下 package com zzg ucas config import java io IOException import org apache http HttpResponse import org apache http
  • TP5.0: 显示错误信息

    在TP5中 我们运行的代码有错误无法执行时 只显示页面错误 而不显示错误信息 对我我来讲是无法接受滴 毕竟我还是个小渣渣 查看了百度 解决方案是 在application config php中找到 我们把false改成true即可 然后我
  • CUDA Samples: heat conduction(模拟热传导)

    以下CUDA sample是分别用C 和CUDA实现的模拟热传导生成的图像 并对其中使用到的CUDA函数进行了解说 code参考了 GPU高性能编程CUDA实战 一书的第七章 各个文件内容如下 funset cpp include funs
  • 【计算机视觉

    文章目录 一 分割 语义相关 12篇 1 1 MeViS A Large scale Benchmark for Video Segmentation with Motion Expressions 1 2 Likelihood Based
  • SCAU-OJ教材习题

    第三章 1 分期还款 加强版 从银行贷款金额为d 准备每月还款额为p 月利率为r 请编写程序输入这三个数值 计算并输出多少个月能够还清贷款 输出时保留1位小数 如果无法还清 请输出 God 计算公式如下 输入格式 三个数 分别为货款金额 每
  • 史上最全的Websocket入门教程

    websocket简介 websocket是什么 答 它是一种网络通信协议 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议 为什么需要websocket 疑问 我们已经有了 HTTP 协议 为什么还需要另一个协议
  • 【力扣】96. 不同的二叉搜索树 <动态规划>

    力扣 96 不同的二叉搜索树 给你一个整数 n 求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种 返回满足题意的二叉搜索树的种数 示例 1 输入 n 3 输出 5 示例 2 输入 n 1 输出 1 提示 1 l
  • Lombok 同时使用 @Data 和 @Builder 的巨坑,千万别乱用!

    1 Lombok 使用演示 Lombok 使 同时使 Data 和 Builder 构建无参构造器报错 编译不通过 如下图 Lombok 使 Data 可以自动 成 参构造和类 所有属性的 getter setter 法 可以简化我们代码的
  • 【Matlab显示空间不足 help memory——已解决 + Matlab上保存的数据太大,导致保存的数据显示只有1KB——已解决】

    Matlab显示空间不足 help memory 已解决 Matlab上保存的数据太大 导致保存的数据显示只有1KB 已解决 问题描述 问题一 方案一 问题一 方案二 问题二 方案 问题描述 1 当处理一些matlab矩阵数据时会出现一些错
  • Flutter LayoutBuilder组件

    文章目录 Flutter LayoutBuilder组件 简书 使用 Flutter LayoutBuilder组件 简书 可以借助LayoutBuilder组件根据不同的屏幕尺寸显示不同的效果 如竖屏和横屏显示的样式不一样 屏幕尺寸介绍
  • 数据分析之非参数检验与二元逻辑回归结果不一致的原因

    在对两组数据进行非参数检验时 各项属性间无统计学差异 但以分类变量作为因变量使用二元逻辑回归进行分析时 其中存在属性p值小于0 05 即该变量对因变量的影响具有显著性 导致该情况的原因 可能是由于两个检验方法所用的假设和检验策略不同所致 非
  • 菜鸟电子面单打印

    一 首先开通电子面单服务 然后自己编辑一个模板 地址 https cloudprint cainiao com print 提示 这里不再详细说明 网上随便找了一个模板地址 如果不会 下面我会提供一个 没有关系 二 需要一台打印机 我的打印

随机推荐

  • 使用 Python 的ChatGPT API 的简单指南

    OpenAI 刚刚发布了 ChatGPT API 这是一个调用 GPT 3 5 Turbo 的 API 与 ChatGPT 产品中使用的模型相同 对于那些已经熟悉 Python 中的 OpenAI API 的人来说 学习如何使用 ChatG
  • Git安装和配置

    Git Gitee 官网安装配置教程 https gitee com help articles 4104 本文是以官网教程为基础而展开的实践笔记 初学者可以以本文为引入 但建议最终以官方文档为最终深入学习的参考 一 下载和安装Git 1
  • 关于scsi锁的故事

    最后更新2021 11 01 一不小心 已经11月了 冬天围着火锅烤串喝啤酒的好日子 scsi锁的出发点很正确 谁用谁锁 用后开锁 目的是避免并行访问的时候有其它不知情的访问变更了数据 更狠毒的是变更了meta数据 整体存储数据结构就乱掉了
  • 微信小程序卖货收费吗?企业公司商家要知道的

    有些小伙伴想做一个微信小程序卖货 就会咨询相关问题 例如微信小程序卖货收费吗 那么下面就和大家探探下这个问题 答案是 收费的 微信小程序卖货收费主要大致有三个地方 一 认证费用 在申请微信小程序账号的时候 要给小程序账号做认证 费用是300
  • 《TensorFlow深度学习》笔记

    import tensorflow as tf from tensorflow import keras from tensorflow keras import datasets import numpy as np import mat
  • phpstudy的mysql服务启动又停止

    前面装了一个MySQL 试了看到的各种方法都不行 试了一下phpmyadmin phpmyadmin通过点击上面的数据库工具打开 发现可以了
  • mongodb常用操作

    只显示某一字段 db extra third 2 2 find name 1 删除字段 db extra third 2 2 remove name null 导出某一个collection usr local app mongodb bi
  • linux永久自动挂载

    给sdb先分两个区 fdisk dev sdb vi etc fstab 永久挂载文件 第1列 挂载设备 想挂谁就写谁 第2列 挂载点 boot 想要永久挂载到根下d1或d2 在这里就写根下d1或d2 第3列 文件系统类型 xfs 格式化成
  • Vue3实现将页面转成PDF并下载或直接打印

    步骤一 安装依赖包 npm i html2canvas npm i jspdf 步骤二 在utils文件夹下新建htmlToPdf js文件 页面导出为pdf格式 import html2Canvas from html2canvas im
  • HASH函数的特点及其应用

    HASH函数必须具备两个基本特征 单向性 和 碰撞约束 单向性是指其的操作方向的不可逆性 在HASH函数中是指 只能从输入推导出输出 而不能从输出计算出输入 碰撞约束是指 不能找到一个输入使其输出结果等于一个已知的输出结果 或者 不能同时找
  • nmap常用指令

    一 Nmap扫描端口常用指令 1 虚拟机的扫描 arp scan l 2 TCP Connect 扫描 通过试图与主机相应的TCP端口建立一个完整的TCP连接 从而判断主机端口的开放信息 nmap sT 域名 IP地址 结果 列出开放的端口
  • 如何在Linux环境下跑Wacom的板子

    文章目录 简介 也许你什么都不需要做 安装Wacom驱动 配置Wacom设备 简介 首先 在Linux环境下使用数位板或者数位屏也算是比较小众的一种需求了 但放在大环境下 各大电影公司例如皮克斯 梦工厂都有极其强大的后期制作能力 甚至强大到
  • java在源目录下根据文件名找到文件并返回绝对路径(递归)

    import java io File public class RecursionDemo2 public static void main String args searchFiles new File D YoudaoDict ex
  • hive -e 和hive -f 的注意点 (//和////)

    原谅我张嘴可能就想骂人 当然跟别人无关 想骂的是自己太年轻 也顺便记录下这个注意点 菜鸟一只 多多见谅 大家都知道 hive f 后面指定的是一个文件 然后文件里面直接写sql 就可以运行hive的sql hive e 后面是直接用双引号拼
  • 如何运用MATLAB实现K-MEANS聚类分析

    由于自己最近在学习聚类分析 也算是一个入门 相当于将自己这段时间的学习成果进行一个总结 分享给更多打算学习聚类分析或者需要用到聚类分析的同学们 在了解K MEANS聚类分析之前 我们首先明确聚类的含义 聚类是将数据分类到不同的类或者簇这样的
  • Springboot 后端配置流程

    概述 分三步 一 从github克隆项目master分支来 git操作步骤 目录 1 配置用户名和邮箱 2 初始化 3 设置仓库地址 4 拉取代码 5 设置保存账号密码时间 6 查看状态 sudo git config global use
  • python中find函数的使用方法_Python re 模块findall() 函数返回值展现方式解析

    findall 函数 在字符串中找到正则表达式所匹配的所有子串 并返回一个列表 如果没有找到匹配的 则返回空列表 注意 match 和 search 是匹配一次 findall 匹配所有 match 和 search 的区别也很大 可以自行
  • 自媒体必备的4个文案网站,每一个都很实用,赶紧收藏

    1 文案狗 在这里 谐音梗 不用担心扣钱 很多广告词 slogan都离不开它 如果实在想不到合适的词 可以在这里搜索 有了这么多的词汇灵感 再也不担心写不出吸睛的广告文案了 是广告人非常喜欢的文案网站 只要输入关键字或者词语 就能生成各种谐
  • 职责链模式

    职责链模式 职责链模式概述 职责链模式解决的问题 角色分析 职责链模式优点 代码示例 源码中的职责链模式使用案例 业务与设计模式落地案例 职责链模式概述 职责链模式解决的问题 案例 一个贷款审批案例 假设贷款额度小于5万时由客户负责人审核放
  • 用python做DEVS离散事件建模与仿真

    1 DEVS 离散事件运行规范 离散事件系统规范 DEVS discrete event system specification 是由美国学者 B P Zeigler等提出的一种模块化建模方法 它将描述对象中的每个子系统看作一个具有内部独