如何解决寻求有关改进 AnyLogic 中的自定义函数的建议
我正在使用旁路距离估算大型城市网络中的最后一英里交付成本。我有超过 8000 个客户代理和 100 多个零售店代理使用经纬度坐标绘制在 GIS 地图中。每个客户都从最近的商店(按路线)接收交货。目标是为每个商店在这个网络中获得两个距离度量:
d0_bar:从商店到所有指定客户的平均距离
d1_bar:同一个店铺所有顾客之间的平均距离
我编写了一个带有简单 foreach 循环的启动函数,以根据路线距离将每个客户分配到一个商店(客户有一个参数,“customer.pStore”类型的商店)。该函数还依次将每个客户添加到商店代理的客户集合(“store.colCusts”;它是一个包含 Customer 类型元素的数组列表)。
接下来,我有一个函数,它遍历商店代理群体并计算上面的两个平均距离度量(d0_bar 和 d1_bar)并将结果写入一个 txt 文件(见下面的代码)。幸运的是,代码有效。然而,问题在于,对于如此庞大的数据集,通过 openstreetmap.org API 遍历所有客户/商店和检索距离的过程需要永远。它已经初始化(“请稍候...”)大约 12 个小时。我该怎么做才能使此代码更有效?或者,AnyLogic 中是否有更好的方法来为我网络中的每个商店获取这两个距离度量?
提前致谢。
//for each store,record all customers assigned to it
for (Store store : stores)
{
distancesstore.print(store.storeCode + "," + store.colCusts.size() + "," + store.colCusts.size()*(store.colCusts.size()-1)/2 + ",");
//calculates average distance from store j to customer nodes that belong to store j
double sumFirstdistByStore = 0.0;
int h = 0;
while (h < store.colCusts.size())
{
sumFirstdistByStore += store.distanceByRoute(store.colCusts.get(h));
h++;
}
distancesstore.print((sumFirstdistByStore/store.colCusts.size())/1609.34 + ",");
//calculates average of distances between all customer nodes belonging to store j
double custdistSumPerStore = 0.0;
int loopLimit = store.colCusts.size();
int i = 0;
while (i < loopLimit - 1)
{
int j = 1;
while (j < loopLimit)
{
custdistSumPerStore += store.colCusts.get(i).distanceByRoute(store.colCusts.get(j));
j++;
}
i++;
}
distancesstore.print((custdistSumPerStore/(loopLimit*(loopLimit-1)/2))/1609.34);
distancesstore.println();
}
解决方法
首先是一些简单的评论:
- 您是否尝试过为单个
distanceByRoute
调用计时?例如。您可以尝试运行store.distanceByRoute(store.colCusts.get(0));
来查看一次调用在您的系统上花费的时间吗?路由通常很慢,但最好知道速度限制是多少。 - 第一个简单的改变是使用 java 并行性。而不是使用这个:
for (Store store : stores)
{ ...
使用这个:
stores.parallelStream().forEach(store -> {
...
});
这将使用 standard Java streams API 并行处理 stores 个条目。
- 它看起来也像第二个循环 - 计算客户之间的平均距离时不考虑镜像。也就是说距离 a->b 等于 b->a。因此,例如,4 个客户将需要 6 次计算:1->2、1->3、1->4、2->3、2->4、3->4。而在 4 个客户的情况下,您的第二个
while
循环将执行 9 次计算: i=0,j in {1,2,3}; i=1,3}; i=2,3},除非我误解了您的意图,否则这似乎是错误的。 - 通常,对于长时间运行的操作,最好包含一些
traceln
以显示相关时间的进度。
请查看上面并发布结果。有了更多信息,可能会进一步提高性能。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。