将时间表的开始和结束值建模为变量

时间:2019-11-26 12:36:03

标签: java anylogic

我正在尝试在Anylogic中构建一个模型,以优化资源池的开始和结束时间以满足需求。有没有一种方法可以将计划的开始时间和结束时间作为参数输入优化模型。我目前的班次是8-5,可以在30天内满足需求,但是优化模型可能会说6-6(我们加班)可以在15天内满足需求。开始和结束时间将具有最小值和最大值。

2 个答案:

答案 0 :(得分:0)

当然可以,但是您需要在模型开始时(即Main启动时)动态创建计划对象,而不是像现在一样通过拖放对象静态创建。 >

选中AnyLogic API,了解如何使用代码创建时间表。作为其中的一部分,您应该能够从一个参数动态定义换档的开始和结束时间(每次优化实验都会对其进行不同的设置)。

答案 1 :(得分:0)

摘要

不幸的是,这并不简单。

在视觉上创建Schedule对象时,必须对开始时间和结束时间进行“硬编码”。因此,要使它们可变(由模型参数驱动),您必须以编程方式创建计划,并确保资源池容量由计划驱动。

如果您在帮助中看到 AnyLogic帮助>函数,表函数和时间表>时间表>时间表API ,它说明了用于创建时间表的编程接口(API),并包括示例模型。但是

  • 该示例根据动态创建的时间表动态设置“源”块到达时间表。您不能对资源池执行此操作。 (不允许动态更改容量定义。)因此,您需要设置一些AnyLogic事件以从计划中更改资源池容量。 (您可以随时随地动态更改资源池的容量。)实际上,这是当您直观地为其设置容量计划时资源池块在内部执行的操作……

  • 该示例用于Rate计划,没有记录任何代码,并且帮助中存在一些错误/缺少正确的解释。 (特别是setPeriod的时间段以您在setTimeUnit 中指定的时间单位,不是以毫秒为单位。)

详细信息

比方说,您的班次是周一至周五,并且您想更改开始/结束时间(最好是改变班次的大小)。因此,我们为它们添加(类型int)模型参数,以及名为workers的资源池。

我们使用整数Schedule来定义资源池容量,因此我们定义了一个变量(类型Schedule<Integer>)来保存该资源(最初为null)。我们还定义了一个动态事件ShiftChange:我们将启动其中的一个“链”,其中每个人都会在下一个时间表更改时触发,并相应地更改资源池容量(使用“图片”调板中的动画时钟以帮助我们更清楚地了解正在发生的事情;您还可以使用“开发者面板”中显示的时间。

动态事件需要具有单个参数shiftSize(类型int):它需要知道将资源池的容量更改为所需的移位大小。

所以Main看起来像这样:

enter image description here

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
[...]

优化用法

现在,您的优化可以根据需要(通过整数模型参数)改变开始/结束时间和平移大小,并根据需要设置最大/最小值。