ns3-gym入门(一):代码结构和简单例子

news2024/9/22 21:12:16

ns3-gym真的好难学,网上可以参考的例子也太少了,如果有用这个做路由的麻烦联系我交流一下吧,太痛苦了

一、安装
之前的文章已经提到过了,这里不赘述了

二、运行简单的例子

用两个终端的方式运行感觉更加直观,但是仍然有些坑:

  1. Terminal 1:最好用sudo模式,可能是哪里的权限不够,反正我只用waf指令时好时坏,也是挺神奇的,这里实际上是在运行/contrib/opengym/examples/目录下,"opengym"文件夹里的"sim.cc",在后续更复杂的例子里,其实ns3环境是配置在"mygym.cc"里面的,最终通过头文件"mygym.h"被"sim.cc"调用
  2. Terminal 2:Ubuntu 20.04自带的protobuf版本相对低了一点,直接运行会报错,所以在运行时先设置环境变量PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python。这里是执行/contrib/opengym/examples/目录下,"opengym"文件夹对应的test.py
# Terminal 1
cd ~/ns-allinone-3.35/ns-3.35
sudo ./waf --run "opengym"

# Terminal 2
cd ~/ns-allinone-3.35/ns-3.35/contrib/opengym/examples/opengym/
PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python ./test.py --start=0

三、例子代码详解
        整体的代码结构图如下,摘自对应的论文。这里的接口主要用的是ZMQ Socket通信,另一个ns3-ai用的是共享内存的方法,据说会比ns3-gym快100倍,但是资料也不多,有时间再试一下

1.基本的接口
        python端:

import gym
import ns3gym
import MyAgent
from ns3gym import ns3env

#env = gym.make('ns3-v0')  <--- causes some errors with the new OpenAI Gym framework, please use ns3env.Ns3Env()
env = ns3env.Ns3Env()
obs = env.reset()
agent = MyAgent.Agent()

while True:
  action = agent.get_action(obs)
  obs, reward, done, info = env.step(action)

  if done:
    break
env.close()

        ns3端:

Ptr<OpenGymSpace> GetObservationSpace();
Ptr<OpenGymSpace> GetActionSpace();
Ptr<OpenGymDataContainer> GetObservation();
float GetReward();
bool GetGameOver();
std::string GetExtraInfo();
bool ExecuteActions(Ptr<OpenGymDataContainer> action);

2.Example1:"opengym"详解
        这个需要sim.cc和test.py对照着来看,懒得打字了,我直接把关键的函数、属性、两个端口的交互画在纸上了:

        首先初始化环境会有一个observation(step0),然后每一轮按照action-obs+reward+done+info的方式迭代(step++),迭代是否结束是sim.cc里面的done布尔值决定的。
        obs收集到的状态是在(low, high)范围内生成的5个随机数,reward是每次迭代+1(我后来改成了reward=action),action是在离散空间下的[0,1,2,3,4],agent通过sample随机选择动作。
        这里还需要对相应的数据类型有一些了解:

        我稍微改动了一下代码,让每一轮迭代更清晰了一些。
        python端:

        ns3端:

PS. 这里和普通的gym环境不太一样:在sim.cc里定义的各个空间函数属性不能改,这个应该是定义在如下的接口回调函数里了,要实现什么功能在对应的函数内部改动就行

  // OpenGym Env
  Ptr<OpenGymInterface> openGym = CreateObject<OpenGymInterface> (openGymPort);
  openGym->SetGetActionSpaceCb( MakeCallback (&MyGetActionSpace) );
  openGym->SetGetObservationSpaceCb( MakeCallback (&MyGetObservationSpace) );
  openGym->SetGetGameOverCb( MakeCallback (&MyGetGameOver) );
  openGym->SetGetObservationCb( MakeCallback (&MyGetObservation) );
  openGym->SetGetRewardCb( MakeCallback (&MyGetReward) );
  openGym->SetGetExtraInfoCb( MakeCallback (&MyGetExtraInfo) );
  openGym->SetExecuteActionsCb( MakeCallback (&MyExecuteActions) );
  Simulator::Schedule (Seconds(0.0), &ScheduleNextStateRead, envStepTime, openGym);

3.Example2:"opengym-2"详解

        运行指令和之前一毛一样,只需要需修改代码路径,还是最好开两个终端(有时候ns3会突然发疯报错,我什么代码都没改它也报错。。。这个时候多半是终端卡住了,重开一个就行)

# Terminal 1
cd ~/ns-allinone-3.35/ns-3.35
sudo ./waf --run "opengym-2"

# Terminal 2
cd ~/ns-allinone-3.35/ns-3.35/contrib/opengym/examples/opengym-2/
PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python ./test.py --start=0

        这个比较特别的是把ns3仿真环境单独写成了mygym.cc,再在sim.cc里面通过头文件mygym.h进行引用,其实具体的obs\reward\action定义都和"opengym"差不多,只是用到了更丰富的数据类型。后面如果要用到比较复杂的ns3环境的话,估计也会这样写更方便调试。
sim.cc(不再具体创建环境了,只是定义一些宏观的参数):

  // OpenGym Env
  Ptr<OpenGymInterface> openGymInterface = CreateObject<OpenGymInterface> (openGymPort);
  Ptr<MyGymEnv> myGymEnv = CreateObject<MyGymEnv> (Seconds(envStepTime));
  myGymEnv->SetOpenGymInterface(openGymInterface);

mygym.h(创建一个自定义的 Gym 环境类,该类继承自OprnGymEnv):

class MyGymEnv : public OpenGymEnv
{
public:
  MyGymEnv ();
  MyGymEnv (Time stepTime);
  virtual ~MyGymEnv ();
  static TypeId GetTypeId (void);
  virtual void DoDispose ();

  Ptr<OpenGymSpace> GetActionSpace();
  Ptr<OpenGymSpace> GetObservationSpace();
  bool GetGameOver();
  Ptr<OpenGymDataContainer> GetObservation();
  float GetReward();
  std::string GetExtraInfo();
  bool ExecuteActions(Ptr<OpenGymDataContainer> action);

private:
  void ScheduleNextStateRead();

  Time m_interval;
};

mygym.cc(对应mygym.h分别进行定义,这里只把和"opengym/sim.cc"不一样的地方贴出来了,后面依然是对各个要素空间的定义,用到了tuplr\dict两种数据类型):

MyGymEnv::MyGymEnv ()
{
  NS_LOG_FUNCTION (this);
  m_interval = Seconds(0.1);

  Simulator::Schedule (Seconds(0.0), &MyGymEnv::ScheduleNextStateRead, this);
}

MyGymEnv::MyGymEnv (Time stepTime)
{
  NS_LOG_FUNCTION (this);
  m_interval = stepTime;

  Simulator::Schedule (Seconds(0.0), &MyGymEnv::ScheduleNextStateRead, this);
}

void
MyGymEnv::ScheduleNextStateRead ()
{
  NS_LOG_FUNCTION (this);
  Simulator::Schedule (m_interval, &MyGymEnv::ScheduleNextStateRead, this);
  Notify();
}

MyGymEnv::~MyGymEnv ()
{
  NS_LOG_FUNCTION (this);
}

TypeId
MyGymEnv::GetTypeId (void)
{
  static TypeId tid = TypeId ("MyGymEnv")
    .SetParent<OpenGymEnv> ()
    .SetGroupName ("OpenGym")
    .AddConstructor<MyGymEnv> ()
  ;
  return tid;
}

void
MyGymEnv::DoDispose ()
{
  NS_LOG_FUNCTION (this);
}

这两个简单的例子其实重在展示基础的交互过程和丰富的数据类型,并没有涉及到强化学习的内核,比如说reward如何基于state(obs)和action定义,action又是怎么作用于state的,要与具体的网络环境耦合还需要更深层次的探索

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

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

相关文章

白嫖3个域名用cloudeflare托管

这也是看到别的up主分享得到的&#xff0c;我也分享一下给你们。 浏览器打开官网 https://register.us.kg/ 然后注册 根据信息填地址电话可以去另一个网页生成&#xff0c;名字姓名之类的可以填自己喜欢的&#xff0c;注意一下&#xff0c;我尝试了一下谷歌的邮箱&#xff0…

webstorm问题解决:无法识别 @

问题解决tsconfig.json 问题 本地的 vite.config.ts 已经配置 路径 但是&#xff0c;我用webstorm 上识别不了 解决 新增文件tsconfig.json&#xff0c;添加 baseUrl 和 paths 的配置&#xff0c;以告诉 TypeScript 和 WebStorm 如何解析路径别名 tsconfig.json {&quo…

以设备为核心的状态自动采集、人工运维和预测性维护为一体的智能管理系统

中服云设备全生命周期管理系统充分利用物联网、人工智能、机器学习、大数据等新一代技术&#xff0c;实现对企业生产设备从采购、安装、调试、使用、维护、维修、改造、更新直到报废全生命周期的智能化、数字化、可视化的实时管控&#xff0c;支持设备运行状态的自动采集和人工…

SketchUp Pro 2023: 强大的跨平台建模软件

SketchUp Pro 2023 是一款广受建筑设计师、工程师和创意设计师欢迎的专业建模软件&#xff0c;它结合了直观的用户界面和强大的功能&#xff0c;为用户提供了创造、设计和分享他们的想法的理想平台。无论是初学者还是经验丰富的专业人士&#xff0c;SketchUp Pro 2023 都能够满…

JVM是如何管理内存的?图文详解GC垃圾回收算法

前言&#xff1a;在C/C中对于变量的内存空间一般都是由程序员手动进行管理的&#xff0c;往往会伴随着大量的 malloc 和 free 操作&#xff0c;常常会有很多问题困扰开发者&#xff0c;这个代码会不会发生内存泄漏&#xff1f;会不会重复释放内存&#xff1f;但是在Java开发中我…

python作业二

# 二进制转化为十进制 num input("num:")def binaryToDecimal(binaryString):he 0length len(binaryString)for i in range(length):he int(binaryString[i]) * 2 ** (length - i - 1)return heprint(binaryToDecimal(num))代码运行如下&#xff1a; import math…

数据结构4.0——串的定义和基本操作

串的定义(逻辑结构) 串&#xff0c;即字符串(String)是由零个或多个字符组成的有序数列。 一般记为Sa1a2....an(n>0) 其中&#xff0c;S是串名&#xff0c;单引号括起来的字符序列是串的值;ai可以是字母、数字或其他字符&#xff1b;串中字符的个数n称为串的长度。n0时的…

印尼Facebook直播网络需要达到什么要求?

在全球化浪潮的推动下&#xff0c;海外直播正受到企业、个人和机构的广泛关注和青睐。无论是用于营销、推广还是互动&#xff0c;海外直播为各种组织提供了更多机会和可能性。本文将探讨在进行印尼Facebook直播前&#xff0c;需要满足哪些网络条件以确保直播的质量和用户体验。…

Codeforces Round 957 (Div. 3) F. Valuable Cards

题目 #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 #define ll long longconst int maxn 1e6 5, inf 1e18, maxm 4e4 5…

容器docker 架构命令案例

文章目录 前言一、docker1.1 为什么有docker1.2 docker架构1.3 docker 安装1.4 docker中央仓库1.5 docker 基本指令1.6 docker数据卷&#xff0c;挂载例&#xff1a;nginx 数据卷挂载例&#xff1a;mysql 本地持久化 1.7 镜像制作镜像结构dockerfile基础指令容器生成镜像 1.8 d…

如何使用Github Page搭建个人网站【踩坑实录多图预警】

读前提示 教程链接&#xff1a;使用GitHub Page创建个人网站和博客 | GitHub 中文社区 点进网站就是非常详细的步骤介绍&#xff0c;基本按部就班来跟着做就OK了&#xff0c;结果不是很熟悉操作&#xff0c;踩了几个坑还是顺利搞定了。 踩坑后的建议&#xff1a;一定要先完成…

百元不入耳耳机哪款好?强推这五款宝藏产品

如今无线蓝牙耳机是年轻人学习通勤、健身娱乐的标配&#xff0c;但普及率极高的入耳式耳机却存在堵塞耳孔、影响外界感知等不足&#xff0c;而开放式耳机的出现恰好弥补了这些不足&#xff0c;受到了越来越多人的欢迎。但要从各种品牌、各类型号的开放式耳机中选出一款最适合自…

数学建模·灰色关联度

灰色关联分析 基本原理 灰色关联分析可以确定一个系统中哪些因素是主要因素&#xff0c;哪些是次要因素&#xff1b; 灰色关联分析也可以用于综合评价&#xff0c;但是由于数据预处理的方式不同&#xff0c;导致结果 有较大出入 &#xff0c;故一般不采用 具体步骤 数据预处理…

Nginx和Tomcat实现负载均衡群集部署应用

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️创作时间&…

20240711每日消息队列-------------MQ消息的积压的折磨

目标 解决MQ消息的积压 背景 菜馆系统----------- 系统读取消息&#xff0c;处理业务逻辑&#xff0c;持久化订单和菜品数据&#xff0c;然后将其显示在菜品管理客户端上。 最初我们的用户基数很小&#xff0c;上线后的一段时间内&#xff0c;MQ消息通信还算顺利。 随着用户…

在Mac上一键安装Mysql(解决所有安装问题)

重点强调安装mysql成功的关键在于安装的版本不能是最新&#xff01;&#xff01; 目录 一&#xff1a;下载mysql数据库安装部分到此结束 二&#xff1a;配置mysql数据库三&#xff1a;启动mysql数据库四&#xff1a;各类奇葩问题总结 一&#xff1a;下载mysql数据库 1.进入MyS…

触摸屏虚拟键盘组件 jQuery Virtual Keyboard使用 自定义键盘

如何在触摸设备上为输入域添加虚拟键盘&#xff1f; 一个插件可以解决这个问题&#xff0c;关键还支持高度自定义&#xff08;git地址&#xff09;&#xff1a; GitHub - Mottie/Keyboard: Virtual Keyboard using jQuery ~ 官网地址&#xff1a;Virtual Keyboard 使用步骤&…

百日筑基第十八天-一头扎进消息队列1

百日筑基第十八天-一头扎进消息队列1 先对业界消息队列有个宏观的认识 消息队列的现状 当前开源社区用的较多的消息队列主要有 RabbitMQ、RocketMQ、Kafka 和Pulsar 四款。 国内大厂也一直在自研消息队列&#xff0c;比如阿里的 RocketMQ、腾讯的 CMQ 和 TubeMQ、京东的 JM…

无头双向非循环链表实现

无头双向非循环链表实现 Ilist.java接口&#xff1a;MyLinkedList.java&#xff1a; 无头双向非循环链表大致与无头单向非循环差不多&#xff0c;只不过每个节点多了个prev引用&#xff0c;可以从后一个节点找到前一个节点。并且除了头节点head&#xff0c;双链表还多了个尾节点…

自定义多选组件

一.业务场景 选择用印公司时&#xff0c;需要选择多个公司&#xff0c;一个公司对应一个实际使用人 点击用印单位&#xff0c;弹出选择公司窗口&#xff0c;选择使用人&#xff0c;同时带上公司ID,点击确定按钮&#xff0c;将公司和使用人回显在用印单位上 二.上代码 wxml代码…