我正试图在任何逻辑中建立一个模型,以优化我的资源池的开始和结束时间,以满足需求。是否有一种方法可以将计划的开始时间和结束时间作为参数输入到优化模型中。目前我的轮班时间为8-5,30天内能满足需求,但优化模型可能会说,6-6 (美国加班)将在15天内满足需求。开始时间和结束时间都有最小值和最大值。
发布于 2019-11-28 12:19:50
摘要
不幸的是,这不是直截了当的。
当您可视化地创建调度对象时,您必须“硬编码”开始和结束时间。因此,要使它们成为变量(从模型参数驱动),您必须以编程方式创建计划,并确保资源池容量由它驱动。
如果在帮助中看到AnyLogic帮助>函数、表函数和计划>调度>调度API,则解释创建计划的编程接口(API),并包含一个示例模型。然而,
setPeriod以您在setTimeUnit中指定的时间单位作为时间段,而不是以毫秒为单位。)详细信息
假设你的轮班是星期一到星期五,你想要改变开始/结束时间(而且,为了更好的衡量,换班的大小)。因此,我们为这些参数添加(类型为int)模型参数,并添加一个名为workers的资源池。
我们使用整数调度来定义资源池容量,因此我们定义了一个变量(类型为Schedule<Integer>)来保存它(最初是null)。我们还定义了一个动态事件ShiftChange:我们将启动其中的“链”,其中每个事件都会在下一个调度更改时间触发,并相应地更改资源池容量(使用来自Pictures调色板的一个动画时钟来帮助我们更清楚地了解正在发生的事情;您还可以使用开发人员面板中显示的时间)。
动态事件需要有一个参数shiftSize (类型为int):它需要知道它需要的移位大小,以将资源池的容量更改为。
所以Main看起来是这样的:

在Main的启动操作中,我们设置了动态调度和动态事件的第一个实例:
dynamicSchedule = new Schedule<Integer>();
dynamicSchedule.setOwner(this);
dynamicSchedule.setCalendarType(true);
dynamicSchedule.setFirstDayOfWeek(MONDAY);
dynamicSchedule.setTimeUnits(TIME_UNIT_WEEK);
dynamicSchedule.setPeriod(1); // Repeats every 1 time unit (week)
dynamicSchedule.setGlueIntervals(true);
dynamicSchedule.setDefaultValue(0); // Default schedule value (0)
// Add intervals for Mon-Fri (day 1-5) from the given start to the end hour with the given shift size
for (int i = 1; i <=5; i++) {
dynamicSchedule.addInterval(1, // startWeek
i, // startDayOfWeek,
startHour, //startHour
0, // startMinute
0, // startSecond
1, // endWeek
i, // endDayOfWeek
endHour, //endHour
0, // endMinute
0, // endSecond
shiftSize); //value
}
dynamicSchedule.initialize(); // Needed to 'take' the changes
// Can't do the below: can't change a ResourcePool's capacity definition dynamically
//workers.set_capacityDefinitionType(CapacityDefinitionType.CAPACITY_SCHEDULE);
//workers.set_capacitySchedule(dynamicSchedule);
// Instead we create a chain of dynamic events to change the Resource Pool capacity as per the schedule
create_ShiftChange(dynamicSchedule.getTimeoutToNextValue(), dynamicSchedule.getNextValue());(有关动态事件详细信息,请参阅本帮助主题:AnyLogic帮助>定义行为。事件和状态图>事件>动态事件。我还包括注释掉的代码,它不适用于在资源池中动态设置容量计划。)
动态事件操作代码如下(连同一条很好的控制台消息,帮助我们检查它是否正常工作):
traceln(format(date()) + ": changing shift size to " + shiftSize);
workers.set_capacity(shiftSize); // Dynamically change the resource pool's capacity
// Set up the next dynamic event in the chain
create_ShiftChange(dynamicSchedule.getTimeoutToNextValue(), dynamicSchedule.getNextValue());在我的例子中,我使用了“开始小时1”、“结束小时3”和“班次大小5”的默认值。如果我在星期一的日期启动该模型,我将得到以下输出(您可以看到资源池容量在变化.):
Nov 25, 2019, 1:00:00 AM: changing shift size to 5
Nov 25, 2019, 3:00:00 AM: changing shift size to 0
Nov 26, 2019, 1:00:00 AM: changing shift size to 5
Nov 26, 2019, 3:00:00 AM: changing shift size to 0
Nov 27, 2019, 1:00:00 AM: changing shift size to 5
Nov 27, 2019, 3:00:00 AM: changing shift size to 0
Nov 28, 2019, 1:00:00 AM: changing shift size to 5
Nov 28, 2019, 3:00:00 AM: changing shift size to 0
Nov 29, 2019, 1:00:00 AM: changing shift size to 5
Nov 29, 2019, 3:00:00 AM: changing shift size to 0
Dec 2, 2019, 1:00:00 AM: changing shift size to 5
Dec 2, 2019, 3:00:00 AM: changing shift size to 0
[...]优化使用
现在,您的优化可以根据需要(通过整数模型参数)改变开始/结束时间和移位大小,根据您的需要设置最大值/最小值。
发布于 2019-11-27 14:58:02
这当然是可能的,但您需要在模型启动时(即启动Main时)动态地创建调度对象,而不是像当前那样通过拖放对象静态地创建。
检查AnyLogic API,了解如何使用代码创建计划。作为其中的一部分,您应该能够从一个参数动态定义shift、start和end时间(每次优化实验都会对其进行不同的设置)。
https://stackoverflow.com/questions/59051127
复制相似问题