The ONE使用笔记:消息事件产生器MessageEventGenerator

本文介绍消息事件产生器MessageEventGenerator及其派生类OneToEachMessageGeneratorOneFromEachMessageGeneratorMessageBurstGenerator

1. 配置文件

消息事件产生器MessageEventGenerator根据参数产生消息创建事件,进而创建消息。消息事件产生器类型对应于消息产生类型。使用方法如下:

# 消息事件产生器类型
Events1.class = MessageEventGenerator

# 消息创建间隔,每隔(25,35)秒产生一个消息,间隔随机从(25,35)产生
Events1.interval = 25,35

# 消息大小,产生消息的大小随机从(min, max)取得,单位是字节
Events1.size = 500k,1M

# Senderaddress range, 值得注意的是,包含下限但不包含上限,即[0, 126)
Events1.hosts = 0,126
# receiver address range,同样,包含下限但不包含上限。若没有设置,被视为与hosts同
Events1.tohosts = 0, 126

# 消息名称的前缀(Message ID prefix),用于标识不同的generator产生的消息
Events1.prefix = M

# 创建消息的时间范围[min, max],默认情况是[0, Scenario.endTime],即整个仿真期间都可以创建消息
Events1.time = 500, 1000

2. 消息事件产生器类型

MessageEventGenerator派生出3种新的消息产生器,即OneToEachMessageGeneratorOneFromEachMessageGeneratorMessageBurstGenerator。The ONE目前共支持4种消息产生方式,其类图如下:

MessageEventGenertor_class_diagram

注:以下内容有些繁琐,建议直接阅读仿真报告《The ONE使用笔记: 消息创建报告CreatedMessagesReport》,更直观。

2.1 MessageEventGenerator

产生的消息是一对一的,以上述配置文件的参数为例,在第32s(随机从25~35选取)产生一个消息,消息大小为800kB(随机从500k~1M选取),源节点是5(随机从0~126选取),目的节点是100(随机从0~126选取)。将消息放入节点5的缓冲区。

2.2 OneToEachMessageGenerator

产生的消息是一对多的(Creates one message from source node/nodes to all destination nodes)。值得注意的是tohosts必须指定。从字面上理解,在每隔interval,消息的源节点从hosts随机选取一个,创建多个消息,其目的节点涵盖所有tohosts。但从源码看并非如此,仿真结果也验证了这一点,消息的源节点从hosts随机选取一个,并不是在单个interval,同时创建多个消息给tohosts,而是各个消息之间的间隔是(25,35)。实际上,用OneToEachMessageGenerator产生消息,整个仿真期间最多产生tohosts个消息。源代码为证:

//OneToEachMessageGenerator.java
public ExternalEvent nextEvent() {
    int responseSize = 0; // no responses requested
    int from;
    int to;

    from = drawHostAddress(hostRange);
    to = this.toIds.remove(0);

    if (to == from) { // skip self 
        if (this.toIds.size() == 0) { // oops, no more from addresses 
            this.nextEventsTime = Double.MAX_VALUE;
            return new ExternalEvent(Double.MAX_VALUE);
        } else {
            to = this.toIds.remove(0);
        }
    }

    if (this.toIds.size() == 0) {
        this.nextEventsTime = Double.MAX_VALUE; // no messages left
    } else {
        this.nextEventsTime += drawNextEventTimeDiff();
    }

    MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(), drawMessageSize(), responseSize, this.nextEventsTime);

    return mce;
}

2.3 OneFromEachMessageGenerator

产生的消息是多对一的(Creates one message from every source node to one of the destination nodes)。值得注意的是tohosts必须指定。从字面上理解,在每隔intervalhosts每个节点产生一个消息给某个目的节点(从tohosts随机选择)。但从源码看并非如此,仿真结果也验证了这一点,每个间隔interval,从剩下的源节点随机选取一个,目的节点从tohosts随机选一个。可见,用OneFromEachMessageGenerator产生消息,整个仿真期间最多产生hosts个消息。源代码为证:

//OneFromEachMessageGenerator.java
public ExternalEvent nextEvent() {
    int responseSize = 0; // no responses requested 
    int from;
    int to;

    from = this.fromIds.remove(0);
    to = drawToAddress(toHostRange, -1);

    if (to == from) { //skip self
        if (this.fromIds.size() == 0) { //no more from addresses
            this.nextEventsTime = Double.MAX_VALUE;
            return new ExternalEvent(Double.MAX_VALUE);
        } else {
            from = this.fromIds.remove(0);
        }
    }

    if (this.fromIds.size() == 0) {
        this.nextEventsTime = Double.MAX_VALUE; //no messages left
    } else {
        this.nextEventsTime += drawNextEventTimeDiff();
    }

    MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(), drawMessageSize(), responseSize, this.nextEventsTime);

    return mce;
}

2.4 MessageBurstGenerator

MessageBurstGenerator产生的消息是多对多。每个interval,每个源节点hosts为每个目的节点tohosts产生一个新消息。直接看源码注释吧:

Creates bursts of messages where every source node creates a new message to every destination node on every interval.

MessageBurstGenerator的nextEvent源代码如下:

//MessageBurstGenerator.java
public ExternalEvent nextEvent() {
    int responseSize = 0; // no responses requested
    int msgSize;
    int interval;
    int from;
    int to;
    boolean nextBurst = false;

    from = this.hostRange[0] + nextFromOffset;
    to = this.toHostRange[0] + nextToOffset;

    if (to == from) {
        to = this.toHostRange[0] + (++nextToOffset);
    }

    msgSize = drawMessageSize();
    MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(), msgSize, responseSize, this.nextEventsTime);

    //其实类似于双重循环, for each host; for each tohosts; 产生一个消息创建事件
    if (to < this.toHostRange[1] - 1) {
        this.nextToOffset++;
    } else {
        if (from < this.hostRange[1] - 1) {
            this.nextFromOffset++;
            this.nextToOffset = 0;
        } else {
            nextBurst = true;
        }
    }

    if (this.hostRange[0] + nextFromOffset == this.toHostRange[0] + nextToOffset) { //to and from would be same for next event 
        nextToOffset++;
        if (nextToOffset >= toHostRange[1]) { 
            nextBurst = true;
        }
    }

    //到下一个hosts
    if (nextBurst) {
        interval = drawNextEventTimeDiff();
        this.nextEventsTime += interval;
        this.nextFromOffset = 0;
        this.nextToOffset = 0;
    }

    if (this.msgTime != null && this.nextEventsTime > this.msgTime[1]) { //next event would be later than the end time
        this.nextEventsTime = Double.MAX_VALUE;
    }

    return mce;
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

25 thoughts on “The ONE使用笔记:消息事件产生器MessageEventGenerator

  • 2017年03月28日 星期二 at 08:13下午
    Permalink

    您好,想请问如何设置两组不同的节点分别产生不同时间间隔的消息

    Reply
    • 2017年03月28日 星期二 at 09:22下午
      Permalink

      Define two message event generators, and specify different values for interval, hosts and tohosts.

      Reply
      • 2017年03月28日 星期二 at 09:36下午
        Permalink

        非常感谢您,还有问题想请教您,就是the one是否有函数可以获取系统当前的时间

      • 2017年03月29日 星期三 at 08:55上午
        Permalink

        我现在还是只是有这个想法,然后还没有具体去编程,因为我是想做一个基于优先级的epidemic路由算法的,是给消息赋优先级,然后这个优先级是随着时间的增加而提高,想法就是通过获取当前系统的时间减去消息进入节点的时间来得到这个相对时间

      • 2017年03月29日 星期三 at 06:43下午
        Permalink

        谢谢您了,还想请教那个如果两组不同的节点如何和两个事件发生器对应起来?

  • 2016年04月27日 星期三 at 07:55下午
    Permalink

    你好,我怎么设置消息事件随时间不断增大?也就是网络负荷随时间不断增大?

    Reply
    • 2016年04月28日 星期四 at 11:28下午
      Permalink

      方法1(比较粗糙)多创建一个消息事件产生器,然后把消息创建时间往后设置。Events1.time = 500, 1000方法2事先用脚本产生标准的消息事件(如:5.0 CONN 1 2 up)

      Reply
      • 2016年05月02日 星期一 at 11:06上午
        Permalink

        你好,对于方法2,看了你的相关博文,在设置消息事件时,已经确定了源节点和目的节点?我是在机会网络下,不知道源节点和目的节点。不知道这个方法是否合适?

      • 2016年05月03日 星期二 at 02:59上午
        Permalink

        Yeah, it really depends on your data flow. BTW, you can randomly assign the source and the destination for messages (randomly choose from the range of your host).

    • 2016年05月03日 星期二 at 08:25下午
      Permalink

      能否给我一下你的联系方式?我们是同一个方向,我的QQ380503638

      Reply
  • 2015年11月02日 星期一 at 09:57上午
    Permalink

    你好,我想请问下 若没有在配置中设置Events.size 的值 那么产生的消息大小是有一个默认的值吗?那个值是多少啊,或者是在哪可以查看默认值是多少呢?

    Reply
  • 2015年10月24日 星期六 at 07:14下午
    Permalink

    你好,我想问问有没有同一个消息发送给多个不同用户的消息产生类?或者要怎么实现?

    Reply
    • 2015年10月24日 星期六 at 09:07下午
      Permalink

      本博文已经列出了The ONE目前支持的所有消息产生类,如果不满足你需求,需要自已实现。

      Reply
  • Pingback: The ONE使用笔记:创建自已的消息事件产生器 | Spark & Shine

  • 2015年03月11日 星期三 at 09:54下午
    Permalink

    你好 好记得我吗?最近模拟仿真碰到个新问题正好这篇文章相关。。就是 每个节点发送信息包的问题。我目前确定以后实验肯定是导入外部数据集而评判标准看了很多经典论文(例如:BUBBLE)。。。大家大概都是采用delivery_prob、overhead_ratio或者hopcount_avg。目前评判标准确定。我就先在也在尝试用自带的一些算法还有网上找的的一些算法,现在做模拟实验。我做实验都是通过“消息事件产生器MessageEventGenerator”随仿真进行,随机产生消息。而近期出来不少结果后,我突然想到个问题便是关于用这种方法产生消息的随机性有多强呢?因为毕竟数据集本身采集时间有限,仿真器仿真时间也是有限的,可能仿真结束时,正好处在随机产生的某个偏值上,正好对某部分节点的传输有利,从而提高了算法的各种指标。反之,会对算法的指标造成影响。这对像infocom06那样数据点比较多的数据集比较有影响。然后我发现随机产生消息和Events1.prefix = M标示有关,相当于一个种子。此标示不同,每次的随机方式就不同,反之随机序列不会改变。然后我改了几个发现还真的有一些影响。各方面指标都有影响。所以,听听你的意见,你觉得未来做实验时,采用什么方式更好一些?我能想到的最原始最客观的方法是换不同标示,多做n次试验,取平均值。。当然 这就是最耗时最麻烦的了。。。

    Reply
    • 2015年03月12日 星期四 at 05:14下午
      Permalink

      @z的平方q 当然记得,最近可好?我还没意识到Events1.prefix不同,产生仿真结果会不同。我看到一些设置文件,是设置不同的随机种子,估计最后求平均值吧。我个人觉得没必要做很多组实验取平均值,因为是这样的吧,仿真时间长一些,就可以降低各项指标的波动。(想想抛硬币,抛的次数多了,自然也就接近理论值0.5)我之前也在想流量模型(traffic model)的事,MessageEventGenerator每隔interval产生一个消息,我在想每个节点每隔随机一段时间产生一个消息,是不是会更好?对了,你打算怎么选取自变量,如TTL、节点数?

      Reply
      • 2015年03月12日 星期四 at 09:46下午
        Permalink

        TTL我看其他论文 范围大概会从1min到1week我觉得5、6个点就可以画了 考虑到很多外部数据集的节点交互稀疏性我取得1h 6h 12h 18h 24h 30h六组实验节点则是外来数据集有多少点 我就设置多少比如infocom06 98个点 我就设置98个

      • 2015年03月12日 星期四 at 10:25下午
        Permalink

        问题没问好,不好意思。我应该问:你打算选取哪些自变量?我觉得至少得考察两个自变量吧。衡量指标好选取(y轴),无非就是delivery probability, overhead ratio, average latency.但x轴挺难选取的,有TTL,消息产生间隔等。难在选了一个自变量,如TTL,如何固定其他变量的值。以你的为例,考察TTL与[delivery probability, overhead ratio, average latency]的影响,如何固定如下参数的值:MessageEventGenerator intervalqueue modebuffer size

      • 2015年03月15日 星期日 at 07:23下午
        Permalink

        选取ttl时,其他变量都不变。包括buffer sizequeue mode然后 考察在此ttl下 delivery probability, overhead ratio, average latency.再改变ttl 考察新的delivery probability, overhead ratio, average latency.看了一些文献,都是保持ttl变化。。。没怎么考察其他的。dtn里貌似ttl影响比较大也可以考虑加一个buffer size

      • 2015年03月16日 星期一 at 04:18下午
        Permalink

        恩,是的。ttl变化,固定其他变量,问题是其他变量应该固定在哪个值?

      • 2015年03月17日 星期二 at 08:03下午
        Permalink

        额 这个还没有这么详细。。。我现在做实验都是缓存50M 每隔2、3分钟产生一个5K大小的消息包。。。节点就是数据集中所有的节点。。模拟时间是数据集的采集时间。。。。我看了你的方向是 网络编码。那么是指DTN中对数据消息的压缩么?那估计缓存的大小是你比较需要的我们实验室导师是搞社会计算的。。然后 想让我参考实验室以前有人做过的DTN(但是不是网络编码方面的)加入社会属性研究东西我看了一些内容觉得未来进一步扩展是考虑怎么发现路由节点,增大传输成功率然后就是在这种移动的社会网络下,分布式的研究。。。

      • 2015年03月17日 星期二 at 10:49下午
        Permalink

        恩,咱们所做的还有有很多交叉的地方。我研究方向是网络编码,你说的对,网络编码会带来一些额外的开销,如buffer,我目前先考虑infinite buffer。现在已经有很多DTN协议就是结合网络的一些社交特性,你可以看下这篇文章:WEI, Kaimin, LIANG, Xiao, et XU, Ke. A survey of social-aware routing protocols in delay tolerant networks: applications, taxonomy and design-related issues. Communications Surveys & Tutorials, IEEE, 2014, vol. 16, no 1, p. 556-578.