您不需要在此处在概念上做任何不同的事情(例如多个代理类型、多个资源池或使用代理继承),并且不需要资源池是“动态的”(无论是动态地向它添加资源和/或它包括多种类型的代理)。 [所有这些都是可能的,但在这里不是必需的,如果你走这些路线,资源池的工作方式会增加一些复杂性。]
只需有一个 Vehicle 代理类型,其属性(通过参数)涵盖不同车辆类型之间的相关差异(这可能只是归结为某些选项列表类型的单个参数,它说明这是哪种类型的车辆,或可能与其他负载有关,例如燃料容量/类型、负载能力等)。
然后您的模型输入(例如通过模型参数或导入数据库的 Excel)将指定您需要的每种“子类型”的车辆数量。初始化资源池,其大小等于这些资源的总和(并确保资源池将它们添加到 Vehicle 类型的自定义填充中,以便您可以显式访问/循环它们)。然后,作为模型初始化的一部分(例如,在Main 的启动操作中),为它们中的每一个设置适当的特定于子类型的属性值。 [还有其他方法可以进行这种初始化;例如,请参阅this question,我的答案在其他答案上有所扩展。]
具体如何执行此操作取决于您的车辆参数是什么以及您如何定义控制它们的输入数据。说你定义
- 带有值
TYPE_A、TYPE_B 和TYPE_C 的选项列表VehicleType
- 模型参数
numTypeA、numTypeB 和 numTypeC 分别定义了您想要的数量
-
Vehicle 只有一个参数 type 的数据类型为 VehicleType 的代理类型
然后一些初始化逻辑(必须为您的自定义人口allVehicles 中的所有车辆设置type)可能如下所示。 (这可以写得更优雅,但下面更容易理解。)
// Set up type A vehicles in population (using relevant indices)
for (int i = 0; i < numTypeA; i++) {
allVehicles.get(i).type = VehicleType.TYPE_A;
}
// Set up type B vehicles in population (using relevant indices)
for (int i = numTypeA; i < numTypeA + numTypeB; i++) {
allVehicles.get(i).type = VehicleType.TYPE_B;
}
// Set up type C vehicles in population (using relevant indices)
for (int i = numTypeA + numTypeB; i < numTypeA + numTypeB + numTypeC; i++) {
allVehicles.get(i).type = VehicleType.TYPE_C;
}
在模型逻辑中,您需要根据要占用的资源来区分它们,请使用相关占用/服务块的“资源选择条件”选项。这通过依次评估每个可用资源的资源选择条件来工作(当前可以通过unit 关键字访问):如果它返回true,则该资源将被占用。显然,条件将取决于您的模型需要如何工作(并且可能取决于执行捕获的代理的属性,可通过 agent 关键字访问),因此可能类似于
agent.weight > 40 ? unit.type == VehicleType.TYPE_A : unit.type == VehicleType.B
(如果执行抓取的代理具有权重,并且您想将 A 型车辆用于重量 > 40 的代理,而 B 型车辆则用于此特定抓取操作。)通常,这将是一个返回 boolean 的函数它接受了执行扣押的代理和当前单元(车辆)作为参数,并执行确定是否选择该车辆所需的任何逻辑。可能是您的选择逻辑不能轻易地在对每个单独的资源说是或否的基础上起作用;例如,如果您的标准是“选择自上次携带某物以来时间最长的车辆”,这意味着所有车辆都知道这一点,以便做出选择。这样的逻辑仍然可以工作,但这更复杂。
如果您希望车辆类型本身是数据驱动的(即,您不想将“硬编码”到模型中 - 例如,通过选项列表 - 可以存在哪些车辆类型),这要复杂得多(因为您还必须制定关于在泛型时使用哪种类型的所有逻辑)但可行。
注意:您可能真正需要的是在某些方面(例如,不同的装载能力)区分您车队中的车辆,而不必明确指定或关心什么'类型'车辆是。这不会改变上述任何内容,除非您不需要 Vehicle 的显式属性(参数)来说明它是什么子类型。