对于我的流程图,我通过不同的来源生成了三个不同的代理。现在我想在流程图的不同块中以不同的方式处理它们。例如,我想为代理设置不同的延迟时间。由于我是 AnyLogic 的新手并且对 Java 不太熟悉,因此我在理解如何处理模型中的代理方面存在问题。
我给了代理一个带有名称的字符串参数,并尝试使用带有 if-else 语句的函数来区分延迟中的代理。我的方法总结如下图(我希望我做对了):

函数中的代码是:
if (agent.TypeComponent == "blade" || agent.TypeComponent == "narcelle")
return uniform(3.5, 6);
else return uniform(1, 3);
Run Code Online (Sandbox Code Playgroud)
我得到错误报告(从德语翻译):
代理无法解析为变量。
Main 类型中的方法 delayPrepFeeder() 不适用于参数 (Agent)
谢谢你和亲切的问候。
简短而简单的答案:您只能让一种代理类型流经您的流程图并正确使用它。因此,要么仅使用一个源,要么确保所有源创建相同的代理类型,例如。成分。以下是有关不同方面的更多详细信息。
每个流程图块都定义了一个代理类型,该块期望:
您仍然可以通过流程图发送与此定义的代理类型不匹配的代理,但您将无法访问其任何变量、参数和函数!如果您仍然尝试访问非定义类型的字段,您将收到此错误:MyField cannot be resolved or is not a field。为什么?因为当您通过访问流动的 Agentagent.时,您正在使用的 Java 类型将是定义的 Agent 类型,或者换句话说,您的 Agent 已被转换为定义的类型,无论他之前的真实类型是什么。
确保在您的源中将新代理和代理类型设置为您的特定代理类型:
新代理设置定义了创建的流动对象的实际类型。代理类型在所有流程图块中都可用,它定义您可以处理流动对象的类型(或者用 Java 语言来说:访问时将其转换为哪种类型agent)。
在您的delayPrepFeeder()函数中,检查您是否定义了输入参数并将其定义为正确的类型。这样做(当然使用您自己的自定义类型名称):
该代码必须使用您刚刚为输入参数定义的名称(此处:myAgent)。在此函数内,您无法使用 直接访问代理agent,这只能直接在流程图块中起作用。因此,我们定义了输入参数myAgent并使用对agent. 同样,流程模块将帮助您调用agent此流程图块中定义的类型的对象引用,该引用必须与 Source 中定义的类型以及您在输入参数和函数中使用的类型相匹配。
if (myAgent.TypeComponent.equalsIgnoreCase("blade") || myAgent.TypeComponent.equalsIgnoreCase("narcelle")){
return uniform(3.5, 6);
}
else {
return uniform(1, 3);
}
Run Code Online (Sandbox Code Playgroud)
你可能不知道。
如果您的类型仅在属性上有所不同,请使用字段(变量和参数)来区分它们。例如,始终使用 Agent 类型Component,然后使用名为 的参数进行区分type。该参数可以是一个字符串(例如:“Rotorblade”),或者甚至可以是AnyLogic 选项列表type中的条目,您可以在其中预先定义所有可能的类型。
您真正需要不同类型的唯一情况是您的代理类型中具有完全不同的(复杂)状态图、动作图、可视化或其他自定义 AnyLogic 元素。
您可以通过使用继承来做到这一点。创建一个“基础”代理(到目前为止只是一个普通代理),例如Component。该基本代理将是您在所有流程图块中设置为流经类型的代理。在这个基本代理中,您添加所有类型通用的并且您想要在流程图中访问的所有变量、参数、函数等。
接下来,您创建继承的代理。再次将它们创建为普通代理类型。您可以通过以下简单的设置使它们从基础代理继承:
现在您将看到,在您的基础代理中定义的内容也将在您继承的代理中显示(灰色):
另一件事:您实际上可以访问继承代理的字段和函数,方法是将其从基本类型转换为正确的类型(MyInheritedAgent)agent:但是,您必须事先确定该对象确实属于这种类型,否则您将收到转换错误。
您可以(不使用继承的代理)每个 AnyLogic 流程图仅使用一种代理类型。因此,请确保代理类型始终在以下位置设置为同一代理类型:
agent:输入参数如果一个还不够,就使用Agent继承。
作为旁注,请使用equals()orequalsIgnoreCase()代替==字符串比较,原因在这里解释。