此文章就来整理一下我学习到的O2DES仿真框架的一些核心知识
核心概念:
模拟器(Simulator):模拟器是O2DES框架的核心组件,用来管理模拟时钟,事件调度和执行。可以通过Simulator类创建模拟环境,并在其中调度和执行事件。
事件(Event):和事件是模拟中发生的关键电子或变化。事件可以是任何需要在特定事件点执行的操作,可以通过继承Event类来创建自定义事件,并在事件中定义其执行逻辑。
资源(Resource):资源是模拟中有限的实体,例如机器,服务器等,资源可以被多个事件共享和竞争,O2DES提供了Resource类,用于管理资源的可用性和分配
随机数生成器(Random Number Generator):随机数生成器用于生成模拟器中所需的随机数,例如事件到达事件,服务事件,可以通过RandomSource类,生成随机数。
概率分布(Probability Distributions):概率分布用于描述事件发生的随机性,例如指数分布,泊松分布等,O2DES提供了多种概率分布类,如Exponential,Poisson等。
常用方法:
创建模拟器:
使用Simulator类创建模拟器实例。
示例:
Simulator simulator = new Simulator();
调度事件:
使用 Schedule
方法在模拟器中调度事件。
示例:
simulator.Schedule(new MyEvent(simulator, 10.0));
运行模拟:
使用 Run
方法启动模拟器,执行所有已调度的事件。
示例:
simulator.Run();
获取当前模拟时间:
使用 Clock
属性获取当前模拟时间
示例:
Console.WriteLine($"Current simulation time: {simulator.Clock}");
创建自定义事件:
通过继承 Event
类创建自定义事件,并重写 Invoke
方法定义事件行为。
public class MyEvent : Event
{
public MyEvent(Simulator simulator, double time) : base(simulator, time)
{
}
public override void Invoke()
{
Console.WriteLine($"Event triggered at time {Simulator.Clock}");
}
}
使用随机数生成器:
使用 RandomSource
类生成随机数。
示例:
double randomValue = simulator.RandomSource.NextDouble();
使用概率分布:
使用概率分布类生成随机时间间隔。
示例:
double arrivalTime = Exponential.Sample(simulator.RandomSource,
TimeSpan.FromMinutes(10));
示例代码
以下是一个简单的生产系统模拟示例,展示如何使用 O2DES 框架的核心概念和方法:
using System;
using O2DESNet;
namespace ProductionSystemSimulation
{
class Program
{
static void Main(string[] args)
{
// 创建模拟器
Simulator simulator = new Simulator();
// 创建生产系统
ProductionSystem productionSystem = new ProductionSystem(simulator);
// 安排第一个生产事件
simulator.Schedule(new ProductionSystem.StartProductionEvent(simulator, 0.0, productionSystem));
// 运行模拟
simulator.Run();
// 输出结果
Console.WriteLine($"\n模拟结束,总产品数: {productionSystem.NumberOfProducts}");
}
}
public class ProductionSystem
{
public Simulator Simulator { get; set; }
public int NumberOfProducts { get; set; } = 0;
public double ProductionRate { get; set; } = 10.0; // 每小时生产 10 个产品
public double FailureProbability { get; set; } = 0.1; // 10% 的概率发生故障
public double RepairTime { get; set; } = 2.0; // 修复时间 2 小时
public ProductionSystem(Simulator simulator)
{
Simulator = simulator;
}
// 开始生产事件
public class StartProductionEvent : Event
{
public ProductionSystem System { get; set; }
public StartProductionEvent(Simulator simulator, double time, ProductionSystem system)
: base(simulator, time)
{
System = system;
}
public override void Invoke()
{
Console.WriteLine($"[{Simulator.Clock}] 开始生产");
// 安排生产完成事件
double productionTime = 60.0 / System.ProductionRate; // 生产一个产品所需的时间(分钟)
Simulator.Schedule(new ProductionCompleteEvent(Simulator, Simulator.Clock + productionTime, System));
}
}
// 生产完成事件
public class ProductionCompleteEvent : Event
{
public ProductionSystem System { get; set; }
public ProductionCompleteEvent(Simulator simulator, double time, ProductionSystem system)
: base(simulator, time)
{
System = system;
}
public override void Invoke()
{
System.NumberOfProducts++;
Console.WriteLine($"[{Simulator.Clock}] 生产完成,总产品数: {System.NumberOfProducts}");
// 检查是否发生故障
if (Simulator.RandomSource.NextDouble() < System.FailureProbability)
{
Console.WriteLine($"[{Simulator.Clock}] 发生故障");
Simulator.Schedule(new RepairCompleteEvent(Simulator, Simulator.Clock + System.RepairTime, System));
}
else
{
// 继续生产
double productionTime = 60.0 / System.ProductionRate; // 生产一个产品所需的时间(分钟)
Simulator.Schedule(new ProductionCompleteEvent(Simulator, Simulator.Clock + productionTime, System));
}
}
}
// 修复完成事件
public class RepairCompleteEvent : Event
{
public ProductionSystem System { get; set; }
public RepairCompleteEvent(Simulator simulator, double time, ProductionSystem system)
: base(simulator, time)
{
System = system;
}
public override void Invoke()
{
Console.WriteLine($"[{Simulator.Clock}] 修复完成,恢复生产");
// 安排新的生产事件
Simulator.Schedule(new StartProductionEvent(Simulator, Simulator.Clock, System));
}
}
}
}
网约车调度系统仿真示例代码
using System;
using O2DESNet;
namespace RideHailingSimulation
{
class Program
{
static void Main()
{
var sim = new Simulator();
var system = new RideHailingSystem(sim, 100); // 100辆网约车
sim.Schedule(new OrderArrivalEvent(sim, 0));
sim.Run();
Console.WriteLine($"完成订单数:{system.CompletedOrders}\n平均等待时间:{system.AvgWaitTime:F1}分钟");
}
}
public class RideHailingSystem
{
public Simulator Sim { get; }
public int AvailableDrivers { get; set; }
public int CompletedOrders { get; set; }
public double TotalWaitTime { get; set; }
public double AvgWaitTime => CompletedOrders > 0 ? TotalWaitTime / CompletedOrders : 0;
public RideHailingSystem(Simulator sim, int totalDrivers)
{
Sim = sim;
AvailableDrivers = totalDrivers;
}
// 订单到达事件(时间驱动)
public class OrderArrivalEvent : Event
{
RideHailingSystem System;
public OrderArrivalEvent(Simulator sim, double time) : base(sim, time)
{
System = (RideHailingSystem)sim.Context;
}
public override void Invoke()
{
// 订单到达(每2-5分钟随机到达)
double orderTime = Sim.Clock;
if(System.AvailableDrivers > 0){
System.AvailableDrivers--;
double serviceTime = 10 + Sim.RandomSource.Next(20); // 服务时间10-30分钟
Sim.Schedule(new OrderCompleteEvent(Sim, Sim.Clock + serviceTime, System, orderTime));
}
else{
// 进入排队等待(事件驱动)
Sim.Schedule(new DriverDispatchEvent(Sim, Sim.Clock + 5, System, orderTime));
}
// 安排下一个订单到达(混合驱动机制)
double nextArrival = 2 + 3 * Sim.RandomSource.NextDouble();
Sim.Schedule(new OrderArrivalEvent(Sim, Sim.Clock + nextArrival));
}
}
// 订单完成事件
public class OrderCompleteEvent : Event
{
RideHailingSystem System;
double _orderTime;
public OrderCompleteEvent(Simulator sim, double time, RideHailingSystem system, double orderTime)
: base(sim, time)
{
System = system;
_orderTime = orderTime;
}
public override void Invoke()
{
System.AvailableDrivers++;
System.CompletedOrders++;
System.TotalWaitTime += (Sim.Clock - _orderTime);
// 阈值触发调度(文献[13]的阈值机制)
if(System.AvailableDrivers > System.TotalDrivers * 0.2)
{
Sim.Schedule(new RelocationEvent(Sim, Sim.Clock + 2, System));
}
}
}
// 车辆调度事件(文献[12]的调度逻辑)
public class RelocationEvent : Event
{
RideHailingSystem System;
public RelocationEvent(Simulator sim, double time, RideHailingSystem system)
: base(sim, time) => System = system;
public override void Invoke()
{
// 执行文献[13]的联合调度策略
int relocateCount = (int)(System.AvailableDrivers * 0.3);
System.AvailableDrivers -= relocateCount;
// 模拟调度耗时(5-15分钟)
double relocateTime = 5 + 10 * Sim.RandomSource.NextDouble();
Sim.Schedule(new RelocationCompleteEvent(Sim, Sim.Clock + relocateTime, System, relocateCount));
}
}
// 调度完成事件
public class RelocationCompleteEvent : Event
{
RideHailingSystem System;
int _relocatedCount;
public RelocationCompleteEvent(Simulator sim, double time, RideHailingSystem system, int count)
: base(sim, time)
{
System = system;
_relocatedCount = count;
}
public override void Invoke()
{
System.AvailableDrivers += _relocatedCount;
Console.WriteLine($"[{Sim.Clock}] 已完成{_relocatedCount}辆车的区域调度");
}
}
// 司机调度事件(文献[12]的等待处理机制)
public class DriverDispatchEvent : Event
{
RideHailingSystem System;
double _orderTime;
public DriverDispatchEvent(Simulator sim, double time, RideHailingSystem system, double orderTime)
: base(sim, time)
{
System = system;
_orderTime = orderTime;
}
public override void Invoke()
{
if(System.AvailableDrivers > 0)
{
System.AvailableDrivers--;
double serviceTime = 10 + Sim.RandomSource.Next(20);
Sim.Schedule(new OrderCompleteEvent(Sim, Sim.Clock + serviceTime, System, _orderTime));
}
else
{
// 继续等待
Sim.Schedule(new DriverDispatchEvent(Sim, Sim.Clock + 5, System, _orderTime));
}
}
}
}
}
以下是逐段解析
程序入口(Main方法)
static void Main()
{
var sim = new Simulator();
var system = new RideHailingSystem(sim, 100); // 100辆网约车
sim.Schedule(new OrderArrivalEvent(sim, 0));
sim.Run();
Console.WriteLine($"完成订单数:{system.CompletedOrders}\n平均等待时间:{system.AvgWaitTime:F1}分钟");
}
- 创建仿真器实例和网约车系统(含100辆初始车辆)
- 安排首个订单到达事件(时间驱动起点)
- 启动仿真引擎并输出运营指标
- 实现文献[2]中提到的空车调度系统初始化流程
网约车系统类(RideHailingSystem)
public class RideHailingSystem
{
// 系统状态属性
public int AvailableDrivers { get; set; }
public int CompletedOrders { get; set; }
public double TotalWaitTime { get; set; }
// 阈值触发机制(文献[13])
public int TotalDrivers => 100;
}
- 实时跟踪可用司机数量和服务完成量
- 计算平均等待时间等KPI指标
- 内置阈值判断逻辑(空闲车辆>20%触发调度)
订单到达事件(OrderArrivalEvent)
public override void Invoke()
{
// 混合驱动机制(文献[1][4])
if(System.AvailableDrivers > 0){
// 即时服务(事件驱动)
double serviceTime = 10 + Sim.RandomSource.Next(20);
Sim.Schedule(new OrderCompleteEvent(...));
}
else{
// 延迟调度(时间驱动)
Sim.Schedule(new DriverDispatchEvent(...));
}
// 泊松过程生成订单(文献[8])
double nextArrival = 2 + 3 * Sim.RandomSource.NextDouble();
Sim.Schedule(new OrderArrivalEvent(...));
}
- 采用泊松过程模拟随机订单到达(平均间隔2-5分钟)
- 集成即时响应与延迟调度双模式
订单完成事件(OrderCompleteEvent)
public override void Invoke()
{
// 资源释放与统计更新
System.AvailableDrivers++;
System.CompletedOrders++;
System.TotalWaitTime += (Sim.Clock - _orderTime);
// 联合调度策略
if(System.AvailableDrivers > System.TotalDrivers * 0.2)
{
Sim.Schedule(new RelocationEvent(...));
}
}
- 基于阈值触发的车辆重定位机制
车辆调度事件(RelocationEvent)
public override void Invoke()
{
// 动态调度算法
int relocateCount = (int)(System.AvailableDrivers * 0.3);
System.AvailableDrivers -= relocateCount;
// 时空成本建模
double relocateTime = 5 + 10 * Sim.RandomSource.NextDouble();
Sim.Schedule(new RelocationCompleteEvent(...));
}
- 按比例调度空闲车辆(30%阈值)
- 引入随机扰动模拟实际路况
调度完成事件(RelocationCompleteEvent)
public override void Invoke()
{
System.AvailableDrivers += _relocatedCount;
Console.WriteLine($"[{Sim.Clock}] 已完成{_relocatedCount}辆车的区域调度");
}
- 记录区域调度完成情况
- 实时更新车辆分布状态
- 支持OD分析
司机调度事件(DriverDispatchEvent)
public override void Invoke()
{
// 递进式重试机制
if(System.AvailableDrivers > 0)
{
// 分配可用车辆
}
else
{
// 等待重试(时间驱动)
Sim.Schedule(new DriverDispatchEvent(...));
}
}