如何找到由数据库填充的 MoveTo 目的地?
Posted
技术标签:
【中文标题】如何找到由数据库填充的 MoveTo 目的地?【英文标题】:How to find a MoveTo destination filled by database? 【发布时间】:2020-04-27 06:44:52 【问题描述】:我可能需要一些关于 Anylogic 模型的帮助。
模型(短):订单按单独路线移动的制造方案。工作场所 (WP) 是由模拟开始动态创建的。它们的名称、数量和其他参数存储在数据库中(excel 导入)。订单也是根据导入创建的。代理群体“订单”有一个集合routing,其中包含它必须按特定顺序停止的工作场所。
Target:我想要 main 中的 moveTo 块,它可以找到代理 order 的下一个目的地。 问题及解决路径:
我将目标类型设置为代理,并在代理字段中输入了函数agent.getDestination()
。此函数按 order 顺序返回集合 WP destinationName = routing.get(i)
的下一个条目。有了这个我得到一个数据类型错误(运行时不编译)。我怀疑这是因为数据库没有将条目保存为 WP 类型,而只有字符串。
是否可以使用 Excel 中的代理创建集合?
在此之后,我尝试使用与 String 相同的 getDestination,因此通过 findFirst 找到与返回名称匹配的 WP,并将其作为 WP 返回。 WP targetWP = findFirst(wps, w->w.name == destinationName);
找不到 wps(工作场所的人口)。
如何搜索人口?
也许与 Agentlink?
我认为这并不难,但找不到答案或解决方案。如您所知,我是初学者...希望描述很好,有人可以帮助我或给我提示:) 谢谢
【问题讨论】:
【参考方案1】:是否可以使用 Excel 中的代理创建集合?
不直接使用集合的属性,并且如您所见,您不能拥有代理类型的数据库 (DB) 列类型。1
但这相对简单,直接通过 Java 代码执行(您可以使用 Insert Database Query 向导为您构建框架代码)。
在此之后,我尝试使用与 String 相同的 getDestination ,因此通过 findFirst 找到与返回名称匹配的 WP 并将其作为 WP 返回
是的,这是一种方法。如果您的订单详细信息在 Excel/数据库中,它们可能是通过一些字符串 ID 引用工作场所(这将是您从单独的 Excel 工作表/数据库表创建的工作场所代理的参数)。您需要使用 Java equals
方法来比较字符串,而不是 ==
(用于比较数字或两个对象是否为同一个对象)。
我想在 main 中找到一个 moveTo 块,它可以找到代理订单的下一个目的地
所以一般的整体解决方案是
从 DB 创建一组 Workplace
代理(假设在 Main 中称为 workplaces
),每个代理都带有一个字符串参数 id
或从 DB 列映射的类似参数。
从数据库中创建一组 Order
代理(假设在 Main 中称为 orders
),然后在其启动操作中设置其工作场所 ID 集合(类型 ArrayList
,元素类String
;假设称为workplaceIDsList
)使用来自另一个数据库表的数据。
Order
可能还需要一个工作变量来存储它需要转到的列表中的下一个索引(假设是一个从 0 开始的 int
变量 nextWorkplaceIndex
)。
在 Main 中编写一个名为 getWorkplaceByID
的函数,它有一个 String
参数 id
并返回一个 Workplace
。这会从与 ID 匹配的人群中获取工作场所;与您类似的单行方式是findFirst(workplaces, w -> w.id.equals(id))
。
MoveTo 块(我认为它在 Main 中)需要将 Order
移动到由 getWorkplaceByID(agent.workplaceIDsList.get(nextWorkplaceIndex++))
定义的代理。 (++
位在评估表达式之后增加索引,以便为下一个工作场所做好准备。)
为了填充集合,您将有两个表,如下所示(假设使用字符串作为工作场所和订单的 ID):
orders
表:您的订单参数列(包括一些字符串id
列)其他,而不是工作场所列表。 (每行创建一个Order
代理。)
order_workplaces
表:列 order_id
、sequence_num
和 workplace_id
(因此,多行指定了订单 ID 的工作场所 ID 序列)。
在Order
的On startup 操作中,通过Insert Database Query 向导设置骨架查询代码,如下所示(我们要循环遍历所有行为此订单的 ID 并做一些事情 --- 我们将更改骨架代码以将条目添加到集合中,而不是像骨架代码那样仅通过 traceln
打印内容。
然后我们编辑骨架代码,如下所示。 (请注意,我们在初始查询中添加了一个orderBy
子句,以便确保我们以升序号顺序获取行。)
List<Tuple> rows = selectFrom(order_workplaces)
.where(order_workplaces.order_id.eq(id))
.orderBy(order_workplaces.sequence_num.asc())
.list();
for (Tuple row : rows)
workplaceIDsList.add(row.get(order_workplaces.workplace_id));
1 AnyLogic 数据库是一个普通的关系数据库 --- HSQLDB 实际上 --- 数据库只了解自己的特定数据类型,如 VARCHAR
,AnyLogic 及其库使用将这些转换为 Java 类型,如 String
。在用户界面中,AnyLogic 使 看起来 您将列类型设置为 int
、String
等,但这些实际上是列内容最终将被转换为的 Java 类型.
AnyLogic 确实支持具有 选项列表 类型的列(以及包含可执行 Java 代码的列的特殊 Code
类型列),但这些是使用特殊逻辑的特殊情况在幕后将列数据(最终仍然是一串字符)转换为适当的选项列表实例或(对于Code
列)转换为即时编译然后执行的 Java)。
【讨论】:
【参考方案2】:欢迎来到 Stack Overflow :) 要通过 Excel 导入创建人口,您必须创建一个方法并像这样调用代码。您还需要一个空的人口。 int n = excelFile.getLastRowNum(YOUR_SHEET_NAME);
for(int i = FIRST_ROW; i <= n; i++)
String name = excelFile.getCellStringValue(YOUR_SHEET_NAME, i, 1);
double SEC_PARAMETER_TO_READ= excelFile.getCellNumericValue(YOUR_SHEET_NAME, i, 2);
WP workplace = add_wps(name, SEC_PARAMETER_TO_READ);
现在,如果您想按名称获取工作场所,则必须创建与您的尝试类似的方法。
函数体:WP workplaceToFind = wps.findFirst(w -> w.name.equals(destinationName));
if(workplaceToFind != null)
//do what ever you want
【讨论】:
这是直接访问 Excel 的旧方式(AnyLogic 7.2 之前)。如今,使用内置的 AnyLogic 数据库,将 Excel 导入内置数据库然后使用查询通常总是更好/更容易(其中许多 AnyLogic 块包括可视化配置要从数据库读取的属性的方法,以及从数据库结构/内容自动创建人口和代理类型定义的方法。以上是关于如何找到由数据库填充的 MoveTo 目的地?的主要内容,如果未能解决你的问题,请参考以下文章