让我来描述一下上面的情况:
函数startAssembly():
if(queue.size()==0 && wait.size()>=1 && resourcePool.idle()>=1){
wait.free(wait.get(0));
}
System.out.println("Queue: " + queue.size());
System.out.println("Wait: " + wait.size());
System.out.println("Idle: " + resourcePool.idle());
函数startAssembly();被称为:
我想要发生什么: 使用通过队列(FIFO)连接的两个进程对装配线进行建模。进程1(汇编程序)比进程2(延迟)快。因此,queueSize1填满,在进程1完成第二部分后,它无法继续工作。通常,工作程序随后显示为busy(),因为代理程序无法离开汇编程序。我希望它在使用函数,等待和队列发生时显示为idle()。
会发生什么:
一个代理程序通过汇编程序,之后没有其他代理程序能够通过等待程序块。通过收集resourcePool.idle(),我注意到即使在代理程序退出程序集块之后,也没有可用资源。我也在if部分尝试过像assembler.delaySize()==0
这样的构造,但也有一些奇怪的行为。用delaySize-part类替换idle-part有效,但它也将2或3个代理传递给汇编程序块。那么"生产线"包含更多的工件。
问题: 这是汇编程序块的正常行为吗?有可能避免这种情况并获得正确的idle() - 金额吗?有没有其他可能的方法来模拟我的"生产线"?
答案 0 :(得分:3)
对于此特定示例,您可以进入模拟实验属性并设置"同时事件的选择模式"到" FIFO(按照调度顺序)"。正如Felipe指出的那样,您需要在第二个源和汇编器之间建立队列。完成这两件事后,您的模型将按预期运行。
资源的发布已放在事件日历上,与其他事件同时发布。当使用默认的LIFO时,最后输入(即,进入队列)首先执行。如果选择FIFO,则资源的发布首先在日历上,因此它发生在其他项之前。
我相信AnyLogic在AnyLogic 7中将默认行为从FIFO更改为LIFO.FIFO似乎是离散事件模拟包中更常用的方法。
答案 1 :(得分:1)
此解决方案在您将LIFO用于同时事件的选择模式时有效,在这种情况下,代理程序从汇编程序移至队列,然后移至queueSize1,然后移至延迟(全部为零时间),在资源被释放之后....这有点违反直觉,但它是在LIFO选择模式下工作的方式。
所以你需要做的是创建一个名为StartAssembly的动态事件,在动态事件中你将调用该函数:startAssembly();
然后在汇编程序的退出程序中,您将调用动态事件几乎立即运行:
create_StartAssembly(0.001);
这将确保资源被释放......并且所有条件都得到满足。
您不需要在其他地方执行相同操作,只需在汇编程序的退出
另外,我认为你应该在source1和汇编程序之间添加一个队列,否则你可能会收到错误