此文章就来整理一下我学习到的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(...));}
}