寻求有关改进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();
}

首先有几个简单的注释:

  1. 您是否尝试过为单个distanceByRoute呼叫计时?例如,你可以试着运行store.distanceByRoute(store.colCusts.get(0));,看看一个调用在你的系统上需要多长时间吗。路由通常很慢,但最好知道限速是多少
  2. 第一个简单的改变是使用java并行性。不用这个:
for (Store store : stores)
{ ...

使用这个:

stores.parallelStream().forEach(store -> {
...
});

这将使用标准Java流API并行处理存储条目。

  1. 它看起来也像是第二个循环——计算客户之间的平均距离时没有考虑镜像。也就是说距离a->b等于b->a.因此,例如,4个客户将需要6个计算:1->2、1->3、1->4、2->3、2->4、3->4.而在4个客户的情况下,您的第二个while循环将执行9个计算:i=0,j在{1,2,3}中;i=1,j在{1,2,3}中;{1,2,3}中的i=2,j,这似乎是错误的,除非我误解了你的意图
  2. 一般来说,对于长时间运行的操作,最好包含一些traceln,以显示相关时序的进度

请查看以上内容并发布结果。有了更多的信息,可能会有更多的性能改进。

最新更新