Author:赵志乾
Date:2024-06-13
Declaration:All Right Reserved!!!
1. 类图
2. 原理解析
EventOriginator是Anylogic中各类事件的父类,对外暴露的接口主要有:
函数 | 功能 |
boolean isActive() | 判定是否存在尚未调度的执行规划 |
double getRest(TimeUnits units) | 获取当前时刻至事件逻辑触发时的时间间隔,当不存在尚未执行的规划时,该函数将返回infinity |
Event是EventOriginator的子类,其主要定义了抽象函数 void reset()和void restart();从这两个函数可以看出Event与DynamicEvent的区别:DynamicEvent是一次性的,一个实例只能做一次规划(没有restart函数将无法重新规划);
EventRate是Event的3个子类之一,其主要用于对符合泊松过程的事件触发场景进行建模;通过在图形编辑窗口拖入Event组件,并选择Trigger Type为Rate,此时Anylogic会自动在容器类中新建与之对应的EventRate实例;为了自定义泊松过程的到达率以及“到达”特性发生时需要执行的逻辑,Anylogic会自动在容器类中生成double evaluateRateOf( EventRate _e )和void executeActionOf( EventRate self )函数;
// 假设事件名为event,且Model时间单位为秒
// 到达率计算函数
@AnyLogicInternalCodegenAPI
public double evaluateRateOf(EventRate _e) {
double _value;
// 获取自定义的到达率
if (_e == event) {
_value = 此处内容为Event组件属性窗口中Rate属性中所填内容;
_value = toModelRate( _value, PER_SECOND );
return _value;
}
return super.evaluateRateOf( _e );
}
// 执行事件发生时的自定义逻辑
@AnyLogicInternalCodegenAPI
public void executeActionOf( EventRate self ) {
if ( self == event) {
// 自定义逻辑,为Event组件属性窗口中Action属性中所填的内容
return ;
}
super.executeActionOf( self );
}
EventRate类核心代码:
//*********************************************************************
// 说明: anylogic内核做了代码混淆。为便于理解,以下代码中涉及的
// 部分变量、函数名做了改写;
//*********************************************************************
// reset函数--取消尚未执行的规划
public void reset() {
this.cancel(); // 取消尚未执行的规划
this.rate = -1.0; // 到达率设置未非法值,到达率大于0才能真正起作用,见restart函数;
}
// 重新生成规划
public void restart() {
this.cancel();
// this.getAgent()获取的是容器智能体,即事件发起智能体;自定义的到达率位于容器智能体中,在此处与EventRate实例关联起来;
this.rate = Math.max(0.0, this.getAgent().evaluateRateOf(this));
if (this.rate > 0.0) {
// exponential(this.rate)返回值为到达率为rate的泊松过程下一次到达时间间隔,plan函数用于重新定义倒计时时间;
this.plan(this.getAgent().exponential(this.rate));
}
}
// 事件启动函数,即第一规划,在容器智能体的start函数中自动调用;
@AnyLogicInternalCodegenAPI
public void start() {
this.rate = Math.max(0.0, this.getAgent().evaluateRateOf(this));
if (this.rate > 0.0) {
this.plan(this.getAgent().exponential(this.rate));
}
}
// 容器智能体onChange()函数内部会调用EventRate实例的onChange();即受容器智能体变更控制;
public void onChange() {
// 只有在原来到达率处于合法值是才会对onChange做出反应,即需要用户显式将EventRate规划启用;
if (this.rate > 0.0)) {
if (this.getAgent().getEngine().d() != this) {
double newVersionRate = Math.max(0.0, this.getAgent().evaluateRateOf(this));
if (newVersionRate != this.rate) {
if (newVersionRate == 0.0) {
this.cancel();
} else {
this.restart();
}
}
}
}
}
// 事件触发时执行逻辑
@AnyLogicInternalAPI
void execute() {
super.execute();
try {
// 自定义逻辑位于容器智能体中,在此处进行关联;
this.getAgent().executeActionOf(this);
} finally {
// Event只能规划一次,对于EventRate而言,其规划被执行后需要重新生成规划;
if (this.rate > 0.0) {
this.rate = Math.max(0.0, this.getAgent().evaluateRateOf(this));
if (this.rate > 0.0) {
this.plan(this.getAgent().exponential(this.rate));
}
}
}
}
3. 应用
EventRate主要用于对符合泊松过程的事件触发场景进行建模,例如:商店顾客到达过程符合泊松过程,统计数据分析出其到达率为每天1000人,则可以通过EventRate描述顾客到达模型;