[Matsim]Matsim学习笔记-drt场景中车辆调度的学习

学习需求

在用matsim实现交通流模拟drt场景时,遇到这样一个问题:车辆接送完乘客后,在没有新的订单之前,车辆一直停在最后一个停靠点上,这样车辆的利用率会较低,想实现一个送完最后一个乘客后,车辆能回到某个点上,在回到某个点的过程中响应新的订单?

调研目的

学习matsim在drt场景中是如何实现车辆的调度、任务的添加、更新以及调度状态的更新的?

调研笔记

1、车辆调度初始化

// 初始化车辆调度(初始时给车辆创建了一个StayTask任务)
DrtTaskFactory taskFactory = new DrtTaskFactoryImpl();
for (DvrpVehicle veh : fleet.getVehicles().values()) {
	veh.getSchedule().addTask(taskFactory.createStayTask(veh, veh.getServiceBeginTime(),veh.getServiceEndTime(), veh.getStartLink()));
}

可以发现车辆初始化时是创建了一个StayTask任务,添加到车辆调度任务列表中
2、调度中添加任务

//调度默认状态,添加新任务后变为PLANNED
private ScheduleStatus status = ScheduleStatus.UNPLANNED;
public void addTask(int taskIdx, Task task) {
    validateArgsBeforeAddingTask(taskIdx, task);
    if (status == ScheduleStatus.UNPLANNED) {
       status = ScheduleStatus.PLANNED;
    }
    AbstractTask t = (AbstractTask)task;
    tasks.add(taskIdx, t);
    t.taskIdx = taskIdx;
    t.status = TaskStatus.PLANNED;
    // update idx of the existing tasks
    for (int i = taskIdx + 1; i < tasks.size(); i++) {
       tasks.get(i).taskIdx = i;
    }
}
这段Java代码是一个addTask方法的实现,是用于向某个任务计划中添加任务。以下是该方法的步骤和逻辑:

参数验证:在添加任务之前,调用validateArgsBeforeAddingTask(taskIdx, task)方法来验证传入的参数是否有效。

状态检查与更新:检查当前计划的状态(status)。如果状态是ScheduleStatus.UNPLANNED,则将其更新为ScheduleStatus.PLANNED。

类型转换:将传入的task参数强制转换为AbstractTask类型。这表明task应该是AbstractTask的实例或其子类的实例。

添加任务:将转换后的任务t插入到tasks列表的指定位置taskIdx。这里假设tasks是一个支持按索引添加元素的列表(如ArrayList)。

设置任务索引:为新添加的任务t设置其索引taskIdx。

设置任务状态:将新添加的任务状态设置为TaskStatus.PLANNED。

更新现有任务索引:遍历tasks列表中taskIdx之后的所有任务,并将它们的索引设置为它们在列表中的位置。这是为了保持任务索引的连续性和正确性。

这段代码假设了几个重要的类和枚举类型:

AbstractTask:一个抽象类,实现了Task接口。
TaskStatus:一个枚举,表示任务的状态,
    enum TaskStatus {
		PLANNED, STARTED, PERFORMED
	}
ScheduleStatus:一个枚举,表示计划的状态,
    enum ScheduleStatus {
    UNPLANNED, PLANNED, STARTED, COMPLETED
}
tasks:一个列表,用于存储任务集合。

3、matsim中的任务类型
有三种任务:Stay、Drive、Stop

public class DrtTaskFactoryImpl implements DrtTaskFactory {
	@Override
	public DrtDriveTask createDriveTask(DvrpVehicle vehicle, VrpPathWithTravelData path, DrtTaskType taskType) {
		return new DrtDriveTask(path, taskType);
	}

	@Override
	public DrtStopTask createStopTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) {
		return new DefaultDrtStopTask(beginTime, endTime, link);
	}

	@Override
	public DrtStayTask createStayTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) {
		return new DrtStayTask(beginTime, endTime, link);
	}
}

4、创建行驶任务

  • 使用taskFactory.createDriveTask方法创建一个新的行驶任务(DrtDriveTask)。这个方法需要车辆对象(vehicleEntry.vehicle)、路径数据(vrpPath)和任务类型(DrtDriveTask.TYPE)。
    下面为创建从停留或者停车任务的link到乘客请求的出发link的行驶任务,并添加到调度任务列表中
//根据起始link和结束link、路径、旅行时间创建vrpPath
VrpPathWithTravelData vrpPath = VrpPaths.createPath(stayOrStopTask.getLink(), request.getFromLink(),
       stayOrStopTask.getEndTime(), detourData.detourToPickup, travelTime);
//根据车辆、vrpPath、任务类型创建行驶任务
beforePickupTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, DrtDriveTask.TYPE);
//添加行驶任务到调度任务列表中
schedule.addTask(stayOrStopTask.getTaskIdx() + 1, beforePickupTask);

5、创建上客停车任务
使用taskFactory.createStopTask方法创建一个新的DrtStopTask上客停车任务。传入车辆、开始时间、计算出的停留时间与请求的最早开始时间中的较大者、以及上客点的link。

DrtStopTask pickupStopTask = taskFactory.createStopTask(vehicleEntry.vehicle, startTime,Math.max(startTime + stopDuration, request.getEarliestStartTime()), request.getFromLink());
schedule.addTask(taskIdx, pickupStopTask);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值